Je souhaite ajouter deux images à une seule image (c'est-à-dire pour une image paysage et pour une autre image au portrait), mais je ne sais pas comment détecter les changements d'orientation à l'aide de Swift langues.
J'ai essayé cette réponse mais cela ne prend qu'une image
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("Landscape")
} else {
print("Portrait")
}
}
Je suis nouveau dans le développement iOS, tout conseil serait grandement apprécié!
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)
}
}
Swift Code ci-dessus mis à jour:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
Swift Utilisation de 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")
}
}
Swift 4 +: Je l'utilisais pour la conception de clavier logiciel, et pour une raison quelconque, la méthode UIDevice.current.orientation.isLandscape
n'arrêtait pas de me dire que c'était Portrait
, alors voici ce que j'ai utilisé à la place:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if(size.width > self.view.frame.size.width){
//Landscape
}
else{
//Portrait
}
}
Si vous utilisez Swift version> = 3.0, vous devez appliquer certaines mises à jour de code, comme d'autres l'ont déjà dit. N'oubliez pas d'appeler super:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// YOUR CODE OR FUNCTIONS CALL HERE
}
Si vous envisagez d'utiliser StackView pour vos images, sachez que vous pouvez effectuer les opérations suivantes:
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
}
Si vous utilisez Interface Builder, n'oubliez pas de sélectionner la classe personnalisée pour cet objet UIStackView dans la section Inspecteur d'identité du panneau de droite. Ensuite, créez simplement (également via Interface Builder) la référence IBOutlet à l'instance UIStackView personnalisée:
@IBOutlet weak var stackView: MyStackView!
Prenez l’idée et adaptez-la à vos besoins. J'espère que cela peut vous aider!
Swift 4
J'ai eu quelques problèmes mineurs lors de la mise à jour de la vue ViewControllers à l'aide de UIDevice.current.orientation
, tels que la mise à jour des contraintes des cellules de la vue table lors de la rotation ou de l'animation de sous-vues.
Au lieu des méthodes ci-dessus, je compare actuellement la taille de la transition à celle des contrôleurs de vue. Cela semble être la bonne voie à suivre car on a accès aux deux à ce stade du code:
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's constraints.
// Ensuring no dequeued cells have old constraints.
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
Sortie sur un 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)
Swift 4.2, RxSwift
Si nous devons recharger collectionView.
NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Swift 4, RxSwift
Si nous devons recharger collectionView.
NotificationCenter.default.rx.notification(NSNotification.Name.UIDeviceOrientationDidChange)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Je pense que la bonne réponse est en réalité une combinaison des deux approches: viewWIllTransition(toSize:)
et NotificationCenter
's UIDeviceOrientationDidChange
.
viewWillTransition(toSize:)
vous notifie avant la transition.
NotificationCenter
UIDeviceOrientationDidChange
vous notifie après.
Tu dois être très prudent. Par exemple, dans UISplitViewController
, lorsque le périphérique effectue une rotation dans certaines orientations, le tableau DetailViewController
apparaît sur le UISplitViewController
's viewcontrollers
et est transféré dans le nom UINavigationController
du maître. Si vous recherchez le contrôleur de vue de détail avant la fin de la rotation, il se peut qu'il n'existe pas et se bloque.
Toutes les contributions précédentes sont correctes, mais une petite remarque:
a) si l'orientation est définie dans la liste de sélection, uniquement un portrait ou un exemple, vous serez pas notifié via viewWillTransition
b) si nous avons de toute façon besoin de savoir si l'utilisateur a fait pivoter l'appareil (par exemple, un jeu ou similaire), nous ne pouvons utiliser que:
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
testé sur Xcode8, iOS11
Pour obtenir l'orientation correcte sur démarrage de l'application, vous devez le vérifier dans viewDidLayoutSubviews()
. Les autres méthodes décrites ici ne fonctionneront pas.
Voici un exemple comment faire:
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()
}
Cela fonctionnera toujours, sur première application, et si vous tournez lorsque l'application est en cours d'exécution.