[英]Force View Controller Orientation in iOS 9
我正在制作一個攝影應用程序,允許以肖像或風景拍攝照片。 由於項目的要求,我不能讓設備方向自動旋轉,但確實需要支持旋轉。
使用以下定位方法時:
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if self.orientation == .Landscape {
return UIInterfaceOrientationMask.LandscapeRight
} else {
return UIInterfaceOrientationMask.Portrait
}
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
if self.orientation == .Landscape {
return UIInterfaceOrientation.LandscapeRight
} else {
return UIInterfaceOrientation.Portrait
}
}
我可以在啟動時正確設置旋轉。 通過更改方向值並調用UIViewController.attemptRotationToDeviceOrientation()
我能夠支持旋轉到新的所需接口。 但是,此旋轉僅在用戶實際移動其設備時發生。 我需要它自動發生。
我可以調用: UIDevice.currentDevice().setValue(targetOrientation.rawValue, forKey: "orientation")
來強制更改,但這會導致其他副作用,因為UIDevice.currentDevice().orientation
只返回從該點開始的setValue上。 (而且非常臟)
有什么我想念的嗎? 我已經研究過關閉並啟動一個新的視圖控制器,但這有其他問題,例如在解除並立即呈現新的視圖控制器時出現持續的UI故障。
編輯:
以下方法對我不起作用:
編輯2:
對潛在解決方案的思考
直接設置方向(使用setValue
)並處理iOS 9上出現的所有副作用(不可接受)
我可以使用當前的解決方案並指示用戶需要旋轉設備。 設備物理旋轉后,UI會旋轉,然后正確鎖定到位。 (差的UI)
我可以找到一種解決方案,強制刷新方向並在沒有物理操作的情況下旋轉。 (我在問什么,並尋找)
手工完成所有工作。 我可以縱向或橫向鎖定界面,並手動旋轉和調整容器視圖的大小。 這是“臟”的,因為它放棄了所有大小類自動布局功能,並導致更重的代碼。 我試圖避免這種情況。
我以前遇到過這個問題,我自己。 我能夠使用簡單的解決方法(和GPUImage )來解決它。 我的代碼在Objective-C中,但我確定你將它轉換為Swift沒有問題。
我首先將項目支持的旋轉設置為我希望支持的所有內容,然后覆蓋相同的UIViewController方法:
-(BOOL)shouldAutorotate {
return TRUE;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
這允許設備旋轉但在縱向模式下將保持不變。 然后開始觀察設備旋轉:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(adjustForRotation:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
如果設備處於縱向模式或橫向,則更新UI:
-(void)adjustForRotation:(NSNotification*)notification
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
{
// UPDATE UI
}
break;
case UIDeviceOrientationLandscapeRight:
{
// UPDATE UI
}
break;
default: // All other orientations - Portrait, Upside Down, Unknown
{
// UPDATE UI
}
break;
}
}
最后,GPUImage根據設備的方向渲染圖像。
[_gpuImageStillCamera capturePhotoAsImageProcessedUpToFilter:last_f
withCompletionHandler:^(UIImage *processedImage, NSError *error) {
// Process the processedImage
}];
我能夠在這個答案的幫助下找到解決方案: 程序化界面方向改變不適用於iOS
我的基本定位邏輯如下:
// Local variable to tracking allowed orientation. I have specific landscape and
// portrait targets and did not want to remember which I was supporting
enum MyOrientations {
case Landscape
case Portrait
}
var orientation: MyOrientations = .Landscape
// MARK: - Orientation Methods
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if self.orientation == .Landscape {
return UIInterfaceOrientationMask.LandscapeRight
} else {
return UIInterfaceOrientationMask.Portrait
}
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
if self.orientation == .Landscape {
return UIInterfaceOrientation.LandscapeRight
} else {
return UIInterfaceOrientation.Portrait
}
}
// Called on region and delegate setters
func refreshOrientation() {
if let newOrientation = self.delegate?.getOrientation() {
self.orientation = newOrientation
}
}
然后,當我想刷新方向時,我會執行以下操作:
// Correct Orientation
let oldOrientation = self.orientation
self.refreshOrientation()
if self.orientation != oldOrientation {
dispatch_async(dispatch_get_main_queue(), {
self.orientationRefreshing = true
let vc = UIViewController()
UIViewController.attemptRotationToDeviceOrientation()
self.presentViewController(vc, animated: false, completion: nil)
UIView.animateWithDuration(0.3, animations: {
vc.dismissViewControllerAnimated(false, completion: nil)
})
})
}
此解決方案具有導致view[Will/Did]Appear
和view[Will/Did]Disappear
的副作用。 我正在使用本地orientationRefreshing
變量來管理再次調用這些方法的哪些方面。
所以我查看了UIDevice的私有頭文件,看起來有兩個setter和兩個屬性定義,用於定位,目前令人困惑。 這就是我所看到的......
@property (nonatomic) int orientation;
@property (nonatomic, readonly) int orientation;
- (void)setOrientation:(int)arg1;
- (void)setOrientation:(int)arg1 animated:(BOOL)arg2;
所以,當我看到你使用了setValue:forKey:
,我想看到有一個合成的setter和getter,老實說,不是100%確定哪一個被設置,哪一個被設備承認..我試圖在一個演示應用程序中使用setValue:forKey:
無濟於事,但是從我過去的一個應用程序中使用了這個技巧,它立刻就完成了這個技巧:)我希望這會有所幫助
UIDevice.currentDevice().performSelector(Selector("setOrientation:"), withObject: UIInterfaceOrientation.Portrait.rawValue)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.