2016-10-26 3 views
4

Wie erkennt man die Orientierungsänderung nach der Verwendung von Swift 3?UIView-Rahmen wird nach der Orientierungsänderung nicht aktualisiert

Ich muss es nach der Änderung erkennen, um die Rahmengröße zu berechnen.

EDIT:

fragte ich diese Frage, weil ich wie in dieser Frage Blick auf Orientierungsänderung neu zeichnen müssen: Can't get background gradient to fill entire screen upon rotation

Ich weiß nicht, wie Antwort zu implementieren, die als eine richtige Antwort gekennzeichnet ist.

habe ich versucht, eine andere Antwort

self.backgroundImageView.layer.sublayers?.first?.frame = self.view.bounds 

aber es funktioniert nicht.

In viewDidLoad() Ich habe

let color1 = UIColor(red: 225.0/255.0, green: 210.0/255.0, blue: 0.0/255.0, alpha: 1.0).cgColor 
     let color2 = UIColor(red: 255.0/255.0, green: 125.0/255.0, blue: 77.0/255.0, alpha: 1.0).cgColor 

     let gradientLayer = CAGradientLayer() 
     gradientLayer.colors = [color1, color2] 
     gradientLayer.locations = [ 0.0, 1.0] 
     gradientLayer.frame = self.view.bounds 

     self.view.layer.insertSublayer(gradientLayer, at: 0) 
+0

__A .__ Sie können sicher sein, die richtige Ansicht-Hierarchie erstellen und versuchen, nicht die Benachrichtigung Kette zu bremsen, die unterstützt durch iOS automatisch; oder __B.__ Sie können "UIDeviceOrientationDidChangeNotification" abonnieren und die Änderungen der Ausrichtung abhören und Ihre benutzerdefinierte Ansicht aktualisieren, wenn dies erforderlich ist. – holex

+0

siehe meine Antwort..Es löst Ihr Problem –

Antwort

10

Die obige Größe Antwort kehrt akzeptiert Rahmen vor transition.So Ihrer Ansicht nach ist nicht updating..You die Rahmengröße erhalten müssen, nachdem der Übergang abgeschlossen wurde.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 

     coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in 

      let orient = UIApplication.shared.statusBarOrientation 

      switch orient { 

      case .portrait: 

       print("Portrait") 

      case .landscapeLeft,.landscapeRight : 

       print("Landscape") 

      default: 

       print("Anything But Portrait") 
      } 

      }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in 
       //refresh view once rotation is completed not in will transition as it returns incorrect frame size.Refresh here   

     }) 
     super.viewWillTransition(to: size, with: coordinator) 

    } 
+1

Ich habe eine Menge Dinge ausprobiert, aber ich konnte keine Lösung finden, die die aktualisierten Viewframes hätte. Die Tatsache, dass der Completion-Handler ausgeführt wird, nachdem die View-Frames das Problem gelöst haben, und Ihre Antwort ist wirklich hilfreich. – harmeet07

6

diese Funktion hinzufügen und Plätze wie im siebenten Orientierungsänderung erkennen:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    if UIDevice.current.orientation.isLandscape { 
     print("Landscape") 
    } else if UIDevice.current.orientation.isPortrait { 
     print("Portrait") 
    } 
} 
+0

Danke! Es funktioniert, aber ich habe ein anderes Problem, wegen dem ich diese Frage an erster Stelle gestellt habe. Ich habe meine Frage aktualisiert. Könntest du es dir anschauen? – user3847113

+0

Versuchen Sie 'self.view.setNeedsLayout()' am Ende Ihrer 'viewDidLoad' –

+0

' self.view.setNeedsLayout() 'funktioniert nicht. – user3847113

5

Um Orientierungsänderung Rückruf erhalten Sie diese Benachrichtigung

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) 
hinzufügen müssen

und Sie müssen diese Methode

implementieren
func rotated() { 
    if(UIDeviceOrientationIsLandscape(UIDevice.current.orientation)) 
    { 
     print("landscape") 
    } 

    if(UIDeviceOrientationIsPortrait(UIDevice.current.orientation)) 
    { 
     print("Portrait") 
    } 
} 
0

Versuchen Sie, diese

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 
    if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) { 

     print("Landscape mode called") 

     if UI_USER_INTERFACE_IDIOM() == .Pad { 
      print("Landscape mode in ipad"); 

     } 
     else 
     { 
      print("Landscape mode in Iphone ") 

     } 
    } else { 
     print("Portrait mode called") 
     if UI_USER_INTERFACE_IDIOM() == .Pad { 

      print("Portrait mode called in ipad") 
     } 
     else 
     { 
      print("Portrait mode called in iphone") 
     } 
    } 
} 
override func willRotateToInterfaceOrientation(toInterfaceOrientation:UIInterfaceOrientation, duration: NSTimeInterval) { 
    print("willRotateToInterfaceOrientation method called"); 
    //Here you can invalidateLayout() 
} 
+1

Das ist nicht korrekt ... Verwenden Sie stattdessen viewWillTransition. –

+0

@Anish y es funktioniert für mich..Sie können nur versuchen, diesen Code –

+1

funktioniert aber viewWillTransition wird nur aufgerufen, wenn Gerät rotiert, aber viewWillLayoutSubviews kann mehrere Male –

2

Hier ist meine Lösung, basierend auf diesen Anforderungen:

(1) Mein Layout benötigt, auf der Dimension größer war noch zu ändern, Höhe oder Breite. (Im Prinzip Portrait oder Landschaft, aber in der Zukunft ...?)

(2) Meine App ist universell, daher konnte ich keine Größenklassen oder Überschreibungen berücksichtigen.

(3) Meine App verfügt auch über eine Fotobearbeitungs-Erweiterung, sodass UIApplication nicht verfügbar war. (Auch orientations wie landscapeLeft und landscapeRight funktionieren bei dieser Art von Erweiterung nicht.)

HINWEIS: Ich füge meine Struktur für AutoLayout der Vollständigkeit halber hinzu.

UIViewController:

var p = [NSLayoutConstraint]() 
var l = [NSLayoutConstraint]() 
var initialOrientation = true 
var isInPortrait = false 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // set up all constraints, including common, portrait and landscape 
    setUpConstraints() 
} 

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 
    if initialOrientation { 
     initialOrientation = false 
     if view.frame.width > view.frame.height { 
      isInPortrait = false 
     } else { 
      isInPortrait = true 
     } 
     orientationChanged() 
    } else { 
     if view.orientationHasChanged(&isInPortrait) { 
      orientationChanged() 
     } 
    } 
} 

func orientationChanged() { 
    // this was split out because of other app-specific logic 
    view.setOrientation(p, l) 
} 

UIView:

extension UIView { 

    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool { 
     // always check against isInPortrait to reduce unnecessary AutoLayout changes! 
     if self.frame.width > self.frame.height { 
      if isInPortrait { 
       isInPortrait = false 
       return true 
      } 
     } else { 
      if !isInPortrait { 
       isInPortrait = true 
       return true 
      } 
     } 
     return false 
    } 
    public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) { 
     NSLayoutConstraint.deactivate(l) 
     NSLayoutConstraint.deactivate(p) 
     if self.bounds.width > self.bounds.height { 
      NSLayoutConstraint.activate(l) 
     } else { 
      NSLayoutConstraint.activate(p) 
     } 
    } 
} 
Verwandte Themen