通用設備開發-iOS 9 分屏適配(監聽SizeClass)

1.iPad分屏原則: 根據iPhone豎屏的展示樣式進行展示

2.根控制器為SplitViewController的情況下,在iPhone豎屏上,默認會顯示SplitViewController的主視圖控制器

3.設置容器視圖: 通過在SplitViewController的主視圖控制器中添加一個容器視圖,在主視圖控制器上顯示TabBarController的界面

1> 獲取容器視圖,當分屏時顯示容器視圖,當未分屏時,隱藏容器視圖
2> 封裝方法,通過分屏與否設置容器視圖是否隱藏
//根據是否分屏來顯隱容器視圖
- (void)showContainerView:(BOOL)show{
    self.containerView.hidden = !show;
}

4.監聽是否分屏:根據是否分屏來顯隱容器視圖

1> 如果判斷是否分屏
如果當前設備為iPad,并且出現了iPhone豎屏的展示樣式 說明正在分屏 -> 判斷當前應用的界面展示樣式(SizeClass) -> 如果SizeClass為 width compact&height regular 則說明正在分屏

2> 代碼監聽SizeClass
UIViewController和UIView類都遵守了"<UITraitEnvironment>"協議
該協議用于監聽和獲取SizeClass的情況

@protocol UITraitEnvironment <NSObject>
@property (nonatomic, readonly) UITraitCollection *traitCollection NS_AVAILABLE_IOS(8_0);
/*! To be overridden as needed to provide custom behavior when the environment's traits change. */
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection NS_AVAILABLE_IOS(8_0);
@end

通過UITraitCollection, 就可以拿到SizeClass信息:

NS_CLASS_AVAILABLE_IOS(8_0) @interface UITraitCollection : NSObject <NSCopying, NSSecureCoding>

- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

- (BOOL)containsTraitsInCollection:(nullable UITraitCollection *)trait;

/*! Returns a trait collection by merging the traits in `traitCollections`. The last trait along any given
 axis (e.g. interface usage) will supercede any others. */
+ (UITraitCollection *)traitCollectionWithTraitsFromCollections:(NSArray<UITraitCollection *> *)traitCollections;

+ (UITraitCollection *)traitCollectionWithUserInterfaceIdiom:(UIUserInterfaceIdiom)idiom;
@property (nonatomic, readonly) UIUserInterfaceIdiom userInterfaceIdiom; // unspecified: UIUserInterfaceIdiomUnspecified

+ (UITraitCollection *)traitCollectionWithDisplayScale:(CGFloat)scale;
@property (nonatomic, readonly) CGFloat displayScale; // unspecified: 0.0

+ (UITraitCollection *)traitCollectionWithHorizontalSizeClass:(UIUserInterfaceSizeClass)horizontalSizeClass;
@property (nonatomic, readonly) UIUserInterfaceSizeClass horizontalSizeClass; // unspecified: UIUserInterfaceSizeClassUnspecified

+ (UITraitCollection *)traitCollectionWithVerticalSizeClass:(UIUserInterfaceSizeClass)verticalSizeClass;
@property (nonatomic, readonly) UIUserInterfaceSizeClass verticalSizeClass; // unspecified: UIUserInterfaceSizeClassUnspecified

+ (UITraitCollection *)traitCollectionWithForceTouchCapability:(UIForceTouchCapability)capability NS_AVAILABLE_IOS(9_0);
@property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability NS_AVAILABLE_IOS(9_0); // unspecified: UIForceTouchCapabilityUnknown

@end

3> 監聽時__ "必須監聽SplitViewController的SizeClass"__,因為分屏時,整體界面(SplitVc)的SizeClass發生了變化,而主視圖控制器的界面(SizeClass)沒有發生變化

將主視圖控制器中封裝的容器視圖顯示與否的方法提到.h中進行聲明,通過SplitViewController監聽視圖是否分屏,設置主視圖的容器視圖顯示與否

#pragma mark -- UITraitEnvironment

// 當SizeClass發生變化后調用
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
    
    // 判斷當前的SizeClass,如果為width compact&height regular 則說明正在分屏
    BOOL isTrait = (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) && (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular);
    
    if (isTrait) {
        // 正在分屏
        NSLog(@"正在分屏");
        JSMasterViewController *masterViewController = self.viewControllers[0];
        [masterViewController showContainerView:isTrait];
        
    }else {
        
        NSLog(@"沒有分屏");
        JSMasterViewController *masterViewController = self.viewControllers[0];
        [masterViewController showContainerView:isTrait];
    }
    
}

未分屏:(主視圖中的容器視圖隱藏)

未分屏.png

分屏:(主視圖中的容器視圖顯示)

分屏.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容