Интересно, есть ли у кого-нибудь хорошие решения для создания в Swift объекта пользовательского интерфейса, похожего на выдвижной ящик, который будет иметь половину ширины экрана в альбомной ориентации и привязан к переднему краю экрана. В книжной ориентации ширина должна быть равна ширине экрана.
У меня есть код, который использует UISheetPresentationController для создания листа и обновления его ширины при повороте устройства. Интересно, смогу ли я тоже установить положение листа. По умолчанию оно центрировано.
import UIKit
// MARK: - SheetNavigationController
/// A `UINavigationController` subclass that automatically handles sheet presentation detents and sizing during device orientation changes.
class SheetNavigationController: UINavigationController, UISheetPresentationControllerDelegate {
/// A closure to be executed when the sheet is dismissed.
var onDismiss: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
configureSheetPresentation()
// Set the delegate to self to handle dismissal.
sheetPresentationController?.delegate = self
NotificationCenter.default.addObserver(self,
selector: #selector(orientationDidChange),
name: UIDevice.orientationDidChangeNotification,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: - UISheetPresentationControllerDelegate
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
onDismiss?()
}
@objc private func orientationDidChange() {
// A small delay is necessary to ensure the orientation change has completed before re-calculating the sheet's properties.
DispatchQueue.main.async {
self.configureSheetPresentation()
}
}
/// Configures the sheet presentation properties, including detents and preferred content size, based on the current device idiom and orientation.
private func configureSheetPresentation() {
guard let sheet = sheetPresentationController else { return }
// iPad configuration
if UIDevice.current.userInterfaceIdiom == .pad {
sheet.detents = [.medium(), .large()]
return
}
// iPhone configuration
let isLandscape = view.window?.windowScene?.interfaceOrientation.isLandscape ?? (view.bounds.width > view.bounds.height)
// Size
let widthScaleFactor: CGFloat = isLandscape ? 0.5 : 1.0
preferredContentSize = CGSize(width: widthScaleFactor * UIScreen.main.bounds.width, height: 0)
// Detents
let heightScaleFactor = isLandscape ? 0.75 : 0.35
let initialDetent = UISheetPresentationController.Detent.custom(identifier: .init("initial")) { _ in
heightScaleFactor * UIScreen.main.bounds.height
}
var detents = [initialDetent]
if !isLandscape {
detents.append(.large())
}
sheet.detents = detents
sheet.selectedDetentIdentifier = initialDetent.identifier
}
}
// MARK: - UIViewController Extension
extension UIViewController {
/// Presents a view controller as a sheet that automatically handles orientation changes.
///
/// - Parameters:
/// - rootViewController: The root view controller for the sheet's navigation stack.
/// - onDismiss: A closure to execute when the sheet is dismissed by the user.
func presentAsSheet(_ rootViewController: UIViewController, onDismiss: (() -> Void)? = nil) {
let navController = SheetNavigationController(rootViewController: rootViewController)
navController.onDismiss = onDismiss
if UIDevice.current.userInterfaceIdiom == .pad {
navController.modalPresentationStyle = .pageSheet
} else {
navController.modalPresentationStyle = .formSheet
}
if let sheet = navController.sheetPresentationController {
sheet.prefersGrabberVisible = true
sheet.largestUndimmedDetentIdentifier = .large
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
}
present(navController, animated: true)
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -landscape
UISheetPresentationController – привязка к переднему краю в ландшафте? ⇐ IOS
Программируем под IOS
1762449431
Anonymous
Интересно, есть ли у кого-нибудь хорошие решения для создания в Swift объекта пользовательского интерфейса, похожего на выдвижной ящик, который будет иметь половину ширины экрана в альбомной ориентации и привязан к переднему краю экрана. В книжной ориентации ширина должна быть равна ширине экрана.
У меня есть код, который использует UISheetPresentationController для создания листа и обновления его ширины при повороте устройства. Интересно, смогу ли я тоже установить положение листа. По умолчанию оно центрировано.
import UIKit
// MARK: - SheetNavigationController
/// A `UINavigationController` subclass that automatically handles sheet presentation detents and sizing during device orientation changes.
class SheetNavigationController: UINavigationController, UISheetPresentationControllerDelegate {
/// A closure to be executed when the sheet is dismissed.
var onDismiss: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
configureSheetPresentation()
// Set the delegate to self to handle dismissal.
sheetPresentationController?.delegate = self
NotificationCenter.default.addObserver(self,
selector: #selector(orientationDidChange),
name: UIDevice.orientationDidChangeNotification,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: - UISheetPresentationControllerDelegate
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
onDismiss?()
}
@objc private func orientationDidChange() {
// A small delay is necessary to ensure the orientation change has completed before re-calculating the sheet's properties.
DispatchQueue.main.async {
self.configureSheetPresentation()
}
}
/// Configures the sheet presentation properties, including detents and preferred content size, based on the current device idiom and orientation.
private func configureSheetPresentation() {
guard let sheet = sheetPresentationController else { return }
// iPad configuration
if UIDevice.current.userInterfaceIdiom == .pad {
sheet.detents = [.medium(), .large()]
return
}
// iPhone configuration
let isLandscape = view.window?.windowScene?.interfaceOrientation.isLandscape ?? (view.bounds.width > view.bounds.height)
// Size
let widthScaleFactor: CGFloat = isLandscape ? 0.5 : 1.0
preferredContentSize = CGSize(width: widthScaleFactor * UIScreen.main.bounds.width, height: 0)
// Detents
let heightScaleFactor = isLandscape ? 0.75 : 0.35
let initialDetent = UISheetPresentationController.Detent.custom(identifier: .init("initial")) { _ in
heightScaleFactor * UIScreen.main.bounds.height
}
var detents = [initialDetent]
if !isLandscape {
detents.append(.large())
}
sheet.detents = detents
sheet.selectedDetentIdentifier = initialDetent.identifier
}
}
// MARK: - UIViewController Extension
extension UIViewController {
/// Presents a view controller as a sheet that automatically handles orientation changes.
///
/// - Parameters:
/// - rootViewController: The root view controller for the sheet's navigation stack.
/// - onDismiss: A closure to execute when the sheet is dismissed by the user.
func presentAsSheet(_ rootViewController: UIViewController, onDismiss: (() -> Void)? = nil) {
let navController = SheetNavigationController(rootViewController: rootViewController)
navController.onDismiss = onDismiss
if UIDevice.current.userInterfaceIdiom == .pad {
navController.modalPresentationStyle = .pageSheet
} else {
navController.modalPresentationStyle = .formSheet
}
if let sheet = navController.sheetPresentationController {
sheet.prefersGrabberVisible = true
sheet.largestUndimmedDetentIdentifier = .large
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
}
present(navController, animated: true)
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79810688/uisheetpresentationcontroller-anchor-to-leading-edge-in-landscape[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия