Quiero agregar dos imágenes a la sola vista de imagen (he.e para el paisaje de una imagen y por otro retrato de la imagen), pero no sé cómo detectar los cambios de orientación en el uso de swift idiomas.

Traté de esta respuesta, pero sólo se necesita una imagen

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.currentDevice().orientation.isLandscape.boolValue {
        print("Landscape")
    } else {
        print("Portrait")
    }
}

Soy nuevo en el desarrollo de iOS,cualquier consejo sería muy apreciada!

  • Podría usted por favor, edita tu pregunta y dar formato a tu código? Usted puede hacer eso con cmd+k cuando tienes tu código seleccionado.
  • compruebe esto hacia fuera stackoverflow.com/questions/25666269/…
  • ¿Se pueden imprimir paisaje/retrato correctamente?
  • sí se imprime correctamente @simpleBob
InformationsquelleAutor Raghuram | 2016-08-11

10 Comentarios

  1. 79
    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)
            }
        }
    • Gracias funciona para imageView,lo que si quiero agregar la imagen de fondo para viewController??
    • Poner un imageView en segundo plano. Dar de restricción para el imageView para la parte superior,inferior,llevando detrás a ViewController vista principal para cubrir todo el fondo.
    • No olvide llamar a super.viewWillTransitionToSize dentro de su método de reemplazo de
    • ¿Sabes por qué yo no puedo reemplazar viewWillTransition al crear subclases de UIView?
    • Hay otro tipo de orientación: .isFlat. Si usted sólo quiere coger portrait sugiero cambiar la cláusula else para else if UIDevice.current.orientation.isPortrait. Nota: .isFlat puede ocurrir tanto, el retrato y el paisaje, y con sólo else {} se forma predeterminada siempre (incluso si es plana paisaje).
  2. 53

    Swift 3
    Código de arriba actualizado:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if UIDevice.current.orientation.isLandscape {
            print("Landscape")
        } else {
            print("Portrait")
        }
    }
    • ¿Sabes por qué yo no puedo reemplazar viewWillTransition al crear subclases de UIView?
    • Este se bloqueará si intenta hacer referencia a cualquiera de las vistas en el controlador.
    • podría por favor explicar por qué será crash?
    • Fue hace 6 meses, cuando me comentó, pero creo que la razón de Xcode dio cuando me lo probé fue una excepción de puntero nulo debido a que la propia vista de que aún no había sido creada, sólo el viewController. Yo podría ser misremembering aunque.
  3. 50

    Swift 3
    El Uso 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")
        }
    }
    • Por qué molestarse con el centro de notificaciones, cuando se puede utilizar el viewWillTransitionToSize delegado, y abstenerse de la adición y eliminación de los observadores?
    • Definitivamente mi enfoque de las necesidades de algún código adicional. Pero lo que realmente «detecta los cambios de orientación».
    • Porque viewWillTransition: anticipa el cambio va a suceder, mientras que el uso de UIDeviceOrientationDidChange es llamada cuando el cambio es total.
    • Yo todavía creo que el comportamiento descrito se puede lograr sin el uso de la potencialmente peligrosa NSNotificationCenter. Por favor, revise la siguiente respuesta, y que me haga saber sus pensamientos: stackoverflow.com/a/26944087/1306884
    • Lo interesante de esta respuesta es que esto le dará la orientación actual, incluso cuando el controlador de vista del shouldAutorotate se establece en false. Esto es útil para las pantallas como la aplicación de la Cámara la pantalla principal–la orientación está cerrada, pero los botones se puede girar.
    • Esta es la respuesta correcta
    • Esto debe ser aceptado respuesta para el manejo de los cambios de orientación, ya que no es reemplazar el método para determinar lo que sucede después de la vista se gira. Por ejemplo, yo tengo una animación que necesito para jugar antes de la vista de la gira y de la pausa después de la gira para mantener el marco de llegar descompone si su pausa cuando la vista se gira.
    • Este método también es útil cuando usted necesita decirle a algunos objetos anidados, que no está conectado directamente a la vista controlador (como una tabla en las celdas de la tabla o vista de colección en una celda de la tabla), que deben ser actualizados. Estos objetos no tienen la viewWillTransitionToSize método de sí mismos. /!\ Pero me di cuenta de algo realmente peligroso comportamiento—esta notificación desencadena por el giroscopio/acelerador incluso cuando se cambia el ángulo frontal del dispositivo sin rotación, lo que puede conducir a no solicitadas tabla de actualización, por ejemplo. Tenga cuidado de usar!
    • La respuesta que @Michael vinculadas deben ser aceptados como respuesta.
    • Como de iOS 9, usted ni siquiera necesita llamar explícitamente a deinit. Usted puede leer más sobre esto aquí: useyourloaf.com/blog/…

  4. 8

    Swift 4+:
    Yo estaba usando esto para teclado de software de diseño, y por alguna razón el UIDevice.current.orientation.isLandscape método me decía que era Portrait, así que aquí es lo que he usado en lugar de:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if(size.width > self.view.frame.size.width){
            //Landscape
        }
        else{
            //Portrait
        }
    }
    • bien, yo tengo un problema similar en mi iMessage de la aplicación. ¿No es muy raro? Y, aunque tu solución funciona todo lo contrario!! _(ツ)_/
    • No utilice UIScreen.principal.los límites, porque se puede dar la pantalla de límites antes de la transición (la mente la «Voluntad» en el método), especialmente en múltiples rápida rotación. Usted debe utilizar el ‘tamaño’ de parámetro…
    • ¿Te refieres a los nativeBounds parámetro?
    • no. El size parámetro que se inyecta en viewWillTransitionToSize:withCoordinator: método escrito anteriormente. Esto refleja el tamaño exacto que su vista se tiene después de la transición.
  5. 5

    Si está utilizando Swift versión >= 3.0 hay algunas actualizaciones del código tiene que aplicar como otros ya han dicho. Pero no te olvides de llamar a super:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    
       super.viewWillTransition(to: size, with: coordinator)
    
       //YOUR CODE OR FUNCTIONS CALL HERE
    
    }

    Si usted está pensando en usar un StackView para tus imágenes tenga en cuenta que usted puede hacer algo como lo siguiente:

    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 está utilizando el Interface Builder no olvides seleccionar la clase personalizada para este UIStackView objeto, en la Identidad del Inspector de la sección en el panel de la derecha. A continuación, acaba de crear (también a través de la Interface Builder) la IBOutlet referencia a la costumbre UIStackView ejemplo:

    @IBOutlet weak var stackView: MyStackView!

    Tomar la idea y adaptarla a sus necesidades. Espero que esto le puede ayudar!

    • Buen punto sobre llamar a super. Es muy descuidado de codificación para no llamar la super método en una función reemplazada y se puede producir un comportamiento impredecible en las aplicaciones. Y, potencialmente, errores que son muy difíciles de localizar!
    • ¿Sabes por qué yo no puedo reemplazar viewWillTransition al crear subclases de UIView?
    • La razón (por lo general) de un objeto de no aplicar una modificación radica en el tiempo de ejecución de la instancia no fue creado con la clase personalizada pero con el defecto de lugar. Si usted está usando la Interfaz del Generador, asegúrese de seleccionar la clase personalizada para este UIStackView objeto, en la Identidad del Inspector de la sección en el panel de la derecha.
  6. 5

    Swift 4

    He tenido algunos pequeños problemas a la hora de actualizar el ViewControllers ver con UIDevice.current.orientation, tales como la actualización de las restricciones de formato tableview las células durante la rotación o la animación de subvistas.

    Lugar de los métodos anteriores, actualmente estoy comparando el tamaño de la transición a la vista de los controladores de vista tamaño. Esto parece la manera correcta de ir, ya que uno tiene acceso a ambos en este punto en el código:

    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()
            }
        }
    
    
    }

    De salida en 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)
    • Debo tener para encender la orientación de apoyo de nivel de proyecto?
  7. 5

    Swift 4.2, RxSwift

    Si tenemos la necesidad de volver a cargar collectionView.

    NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification)
        .observeOn(MainScheduler.instance)
        .map { _ in }            
        .bind(to: collectionView.rx.reloadData)
        .disposed(by: bag)

    Swift 4, RxSwift

    Si tenemos la necesidad de volver a cargar collectionView.

    NotificationCenter.default.rx.notification(NSNotification.Name.UIDeviceOrientationDidChange)
        .observeOn(MainScheduler.instance)
        .map { _ in }            
        .bind(to: collectionView.rx.reloadData)
        .disposed(by: bag)
    • ahora es UIDevice.orientationDidChangeNotification
    • gracias por las actualizaciones
  8. 3

    Creo que la respuesta correcta es en realidad una combinación de ambos enfoques: viewWIllTransition(toSize:) y NotificationCenter‘s UIDeviceOrientationDidChange.

    viewWillTransition(toSize:) le notifica antes de la transición.

    NotificationCenter UIDeviceOrientationDidChange le notifica después de.

    Tienes que ser muy cuidadoso. Por ejemplo, en UISplitViewController cuando el dispositivo gira en ciertas orientaciones de la DetailViewController obtiene desprendió la UISplitViewController‘s viewcontrollers matriz, y que se inserta en el máster UINavigationController. Si ir en busca de la vista de detalles del controlador antes de la rotación ha terminado, no puede existir y choque.

  9. 3

    Todo lo anterior contribuye están bien, pero un poco de nota:

    a) si la orientación se establece en plist, sólo un retrato o un ejemplo, Usted será no notificados a través de viewWillTransition

    b) si de todas formas necesita saber si el usuario ha girado dispositivo (por ejemplo un juego o similar..) sólo podemos utilizar:

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

    probado en Xcode8, iOS11

  10. 1

    Para obtener la orientación correcta en aplicación de inicio usted tiene que comprobar en viewDidLayoutSubviews(). Otros métodos que se describen aquí no funciona.

    He aquí un ejemplo de cómo hacerlo:

    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()
    }

    Esto va a funcionar siempre, en primera aplicación de inicio, y si gira mientras la aplicación se está ejecutando.

Dejar respuesta

Please enter your comment!
Please enter your name here