Swift - Как определить изменения ориентации
Я хочу добавить два изображения в один вид изображения (например, для одного пейзажа и для портрета другого изображения), но я не знаю, как определить изменения ориентации с помощью быстрых языков.
Я пробовал этот ответ, но требуется только одно изображение
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("Landscape")
} else {
print("Portrait")
}
}
Я новичок в разработке iOS, любые советы будут очень благодарны!
Ответы
Ответ 1
let const = "Background" //image name
let const2 = "GreyBackground" // image name
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: const)
// Do any additional setup after loading the view.
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
imageView.image = UIImage(named: const2)
} else {
print("Portrait")
imageView.image = UIImage(named: const)
}
}
Ответ 2
Swift 3
Выше кода обновлен:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
Ответ 3
Swift 3 Использование NotificationCenter
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
func rotated() {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
Ответ 4
Свифт 4+: я использовал это для создания мягкой клавиатуры, и по какой-то причине метод UIDevice.current.orientation.isLandscape
продолжал говорить мне, что это Portrait
, поэтому здесь я использовал вместо этого:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if(size.width > self.view.frame.size.width){
//Landscape
}
else{
//Portrait
}
}
Ответ 5
Swift 4.2, RxSwift
Если нам нужно перезагрузить collectionView.
NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Swift 4, RxSwift
Если нам нужно перезагрузить collectionView.
NotificationCenter.default.rx.notification(NSNotification.Name.UIDeviceOrientationDidChange)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Ответ 6
Если вы используете Swift version> = 3.0, вам нужно применить некоторые обновления кода, как уже говорили другие. Просто не забудьте позвонить супер:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// YOUR CODE OR FUNCTIONS CALL HERE
}
Если вы подумываете использовать StackView для своих изображений, вы можете сделать что-то вроде следующего:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
stackView.axis = .horizontal
} else {
stackView.axis = .vertical
} // else
}
Если вы используете Interface Builder, не забудьте выбрать пользовательский класс для этого объекта UIStackView в разделе Identity Inspector на правой панели. Затем просто создайте (также через Interface Builder) ссылку IBOutlet на пользовательский экземпляр UIStackView:
@IBOutlet weak var stackView: MyStackView!
Возьмите идею и приспособите ее к вашим потребностям. Надеюсь, это поможет вам!
Ответ 7
Swift 4
У меня возникли некоторые незначительные проблемы при обновлении представления ViewControllers с использованием UIDevice.current.orientation
, таких как обновление ограничений элементов tableview во время вращения или анимации подвью.
Вместо приведенных выше методов я в настоящее время сравниваю размер перехода с размером представления диспетчера представлений. Это похоже на правильный путь, так как у вас есть доступ к обоим в этом пункте кода:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("Will Transition to size \(size) from super view size \(self.view.frame.size)")
if (size.width > self.view.frame.size.width) {
print("Landscape")
} else {
print("Portrait")
}
if (size.width != self.view.frame.size.width) {
// Reload TableView to update cell constraints.
// Ensuring no dequeued cells have old constraints.
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
Выход на iPhone 6:
Will Transition to size (667.0, 375.0) from super view size (375.0, 667.0)
Will Transition to size (375.0, 667.0) from super view size (667.0, 375.0)
Ответ 8
Все предыдущие вложения в порядке, но небольшая заметка:
а) если ориентация установлена в Plist, только портрет или, например, Вы будете не уведомлены через viewWillTransition
б) если нам все равно нужно знать, имеет ли пользователь вращающееся устройство (например, игру или подобное.), мы можем использовать только:
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
проверено на Xcode8, iOS11
Ответ 9
Я считаю, что правильный ответ на самом деле представляет собой комбинацию обоих подходов: viewWIllTransition(toSize:)
и NotificationCenter
UIDeviceOrientationDidChange
.
viewWIllTransition(toSize:)
уведомляет вас о перед.
NotificationCenter
UIDeviceOrientationDidChange
уведомляет вас после.
Вы должны быть очень осторожны. Например, в UISplitViewController
, когда устройство вращается в определенные ориентации, DetailViewController
выталкивается из массива UISplitViewController
viewcontrollers
и нажимается на главный UINavigationController
. Если вы перейдете к поиску контроллера подробного представления до завершения вращения, он может не существовать и сбой.
Ответ 10
Чтобы получить правильную ориентацию в начале приложения, вы должны проверить его в viewDidLayoutSubviews()
. Другие методы, описанные здесь, не будут работать.
Вот пример, как это сделать:
var mFirstStart = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if (mFirstStart) {
mFirstStart = false
detectOrientation()
}
}
func detectOrientation() {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
// do your stuff here for landscape
} else {
print("Portrait")
// do your stuff here for portrait
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
detectOrientation()
}
Это будет работать всегда, при первом запуске приложения и при повороте во время работы приложения.