我想将两个图像添加到单个图像视图(即用于横向一个图像和用于纵向另一个图像),但我不知道如何使用快速语言检测方向变化.
我试过这个答案,但它只需要一张图片
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("Landscape")
} else {
print("Portrait")
}
}
Run Code Online (Sandbox Code Playgroud)
我是iOS开发的新手,任何建议都将不胜感激!
小智 86
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)
}
}
Run Code Online (Sandbox Code Playgroud)
Yar*_*Bai 60
Swift 3 以上代码更新:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
Run Code Online (Sandbox Code Playgroud)
mas*_*vsa 56
Swift 3 使用NotificationCenter
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
}
func rotated() {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
Run Code Online (Sandbox Code Playgroud)
Wil*_*set 47
你真的应该区分:
这两个值不匹配的情况有很多,例如:
在大多数情况下,您会希望使用界面方向,并且可以通过窗口获取它:
private var windowInterfaceOrientation: UIInterfaceOrientation? {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
}
Run Code Online (Sandbox Code Playgroud)
如果您还想支持 < iOS 13(例如 iOS 12),您可以执行以下操作:
private var windowInterfaceOrientation: UIInterfaceOrientation? {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
} else {
return UIApplication.shared.statusBarOrientation
}
}
Run Code Online (Sandbox Code Playgroud)
现在您需要定义对窗口界面方向变化做出反应的位置。有多种方法可以做到这一点,但最佳解决方案是在
willTransition(to newCollection: UITraitCollection.
这个可以被覆盖的继承的 UIViewController 方法将在每次界面方向改变时触发。因此,您可以在后者中进行所有修改。
这是一个解决方案示例:
class ViewController: UIViewController {
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
coordinator.animate(alongsideTransition: { (context) in
guard let windowInterfaceOrientation = self.windowInterfaceOrientation else { return }
if windowInterfaceOrientation.isLandscape {
// activate landscape changes
} else {
// activate portrait changes
}
})
}
private var windowInterfaceOrientation: UIInterfaceOrientation? {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
}
}
Run Code Online (Sandbox Code Playgroud)
通过实施此方法,您将能够对界面的任何方向变化做出反应。但请记住,它不会在应用程序打开时触发,因此您还必须手动更新viewWillAppear().
我创建了一个示例项目,它强调了设备方向和界面方向之间的区别。此外,它将帮助您了解不同的行为,具体取决于您决定更新 UI 的生命周期步骤。
随意克隆并运行以下存储库:https : //github.com/wjosset/ReactToOrientation
Nic*_* S. 10
这是一个现代的组合解决方案:
import UIKit
import Combine
class MyClass: UIViewController {
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter
.default
.publisher(for: UIDevice.orientationDidChangeNotification)
.sink { [weak self] _ in
let orientation = UIDevice.current.orientation
print("Landscape: \(orientation.isLandscape)")
}
.store(in: &subscriptions)
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 3: 我用它来进行软键盘设计,出于某种原因,UIDevice.current.orientation.isLandscape方法一直告诉我它是"Portrait",所以这就是我用过的东西:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if(size.width > self.view.frame.size.width){
//Landscape
}
else{
//Portrait
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 4.2,RxSwift
如果需要重新加载collectionView。
NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Run Code Online (Sandbox Code Playgroud)
迅捷4,RxSwift
如果需要重新加载collectionView。
NotificationCenter.default.rx.notification(NSNotification.Name.UIDeviceOrientationDidChange)
.observeOn(MainScheduler.instance)
.map { _ in }
.bind(to: collectionView.rx.reloadData)
.disposed(by: bag)
Run Code Online (Sandbox Code Playgroud)
我认为正确的答案实际上是两者的结合方法:viewWIllTransition(toSize:)和NotificationCenter的UIDeviceOrientationDidChange。
viewWillTransition(toSize:)在转换之前通知您。
NotificationCenter UIDeviceOrientationDidChange通知你之后。
你必须非常小心。例如,UISplitViewController当设备旋转到特定方向时,DetailViewController会从UISplitViewController'sviewcontrollers数组中弹出,并推到主设备的UINavigationController. 如果您在旋转完成之前搜索详细视图控制器,它可能不存在并崩溃。
如果您使用的是Swift版本> = 3.0,则必须执行某些代码更新,就像其他人已经说过的那样。只是不要忘了调用super:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// YOUR CODE OR FUNCTIONS CALL HERE
}
Run Code Online (Sandbox Code Playgroud)
如果您想对图像使用StackView,请注意可以执行以下操作:
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
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Interface Builder,请不要忘记在右侧面板的Identity Inspector部分中为此UIStackView对象选择自定义类。然后只需创建(也通过Interface Builder)对自定义UIStackView实例的IBOutlet引用:
@IBOutlet weak var stackView: MyStackView!
Run Code Online (Sandbox Code Playgroud)
采纳想法并使其适应您的需求。希望这可以帮到你!
斯威夫特4
使用来更新ViewControllers视图时,我遇到了一些小问题UIDevice.current.orientation,例如在旋转或子视图动画期间更新表视图单元的约束。
代替上面的方法,我目前正在将过渡大小与视图控制器的视图大小进行比较。这似乎是正确的方法,因为在此刻可以访问两个代码:
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()
}
}
}
Run Code Online (Sandbox Code Playgroud)
在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)
Run Code Online (Sandbox Code Playgroud)
小智 5
转换完成后,您可以使用viewWillTransition(to:with:)并点击来获取界面方向。animate(alongsideTransition:completion:)您只需定义并实现与此类似的协议即可利用该事件。请注意,此代码用于 SpriteKit 游戏,您的具体实现可能有所不同。
protocol CanReceiveTransitionEvents {
func viewWillTransition(to size: CGSize)
func interfaceOrientationChanged(to orientation: UIInterfaceOrientation)
}
Run Code Online (Sandbox Code Playgroud)
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
guard
let skView = self.view as? SKView,
let canReceiveRotationEvents = skView.scene as? CanReceiveTransitionEvents else { return }
coordinator.animate(alongsideTransition: nil) { _ in
if let interfaceOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation {
canReceiveRotationEvents.interfaceOrientationChanged(to: interfaceOrientation)
}
}
canReceiveRotationEvents.viewWillTransition(to: size)
}
Run Code Online (Sandbox Code Playgroud)
您可以在这些函数中设置断点,并观察始终以更新的方向interfaceOrientationChanged(to orientation: UIInterfaceOrientation)调用该断点。viewWillTransition(to size: CGSize)
| 归档时间: |
|
| 查看次数: |
79807 次 |
| 最近记录: |