如何使用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)
答案 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")
}