方向改变后UIView框架未更新

时间:2016-10-26 12:35:34

标签: ios swift

如何使用Swift 3检测方向变化?

我需要在更改后检测它以计算帧大小。

编辑:

我问了这个问题,因为我需要重新定位方向更改的视图,例如:Can't get background gradient to fill entire screen upon rotation

我不知道如何实施标记为正确答案的答案。

我尝试了另一个答案

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

但它不起作用。

viewDidLoad()我有

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)

7 个答案:

答案 0 :(得分:22)

以上接受的答案在转换之前返回帧大小。因此您的视图不会更新。您需要在转换完成后获取帧大小。

from twisted.internet import tksupport, reactor

答案 1 :(得分:6)

添加此功能,您将检测方向更改:

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

答案 2 :(得分:6)

要获得方向更改回调,您需要添加此通知

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

你需要实现这个方法

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

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

答案 3 :(得分:2)

根据这些要求,这是我的解决方案:

(1)我的布局需要根据哪个尺寸更大,更高或更宽来改变。 (基本上是肖像或风景,但将来......?)

(2)我的应用程序是通用的,因此我无法考虑大小类或与它们相关的任何覆盖。

(3)我的应用程序还有一个照片编辑扩展,因此UIApplication不可用。 (此外,landscapeLeft和landscapeRight等方向在此类扩展中不起作用。)

注意:我正在为AutoLayout添加我的结构以保证完整性。

<强>的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)
        }
    }
}

答案 4 :(得分:0)

试试这个

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

答案 5 :(得分:0)

override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {

    self.sliding.setNeedsDisplay()

}

答案 6 :(得分:0)

如果您使用它来获取traitCollection的更新值,请使用它

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    print("Trait collection changes")

}