iOS13适配【灵活控制模态展示的视图样式】(全屏/下滑返回)文中提供完整demo源码

2021/7/1 14:21:57

本文主要是介绍iOS13适配【灵活控制模态展示的视图样式】(全屏/下滑返回)文中提供完整demo源码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 前言

  • 1、灵活控制模态展示的视图样式(全屏/下滑返回)的开发步骤

  •  

    • 1.1 监听presentViewController

    • 1.2 定义app中模态展示的视图为全屏样式的VC

    • 1.3 根据定义的规则,返回Modal风格类型

  • II、完整demo源码

  • see also

  •  

 

 

 

前言
  • 背景

对于【present 半屏】的新特性,至少有两种场景不适用:
1、 列表界面需要支持下拉刷新
2、 模态展示之后,需要特殊处理用户点击返回箭头事件。(比如当编辑商品价格的时候,用户编辑一般放弃不保存,而是点击下滑/返回,这个时候需要还原数据信息)

1、灵活控制模态展示的视图样式(全屏/下滑返回)的开发步骤

1.1 监听presentViewController

  • UIViewController+ERPPresent13.h

#import <objc/runtime.h>


NS_ASSUME_NONNULL_BEGIN

@interface UIViewController (ERPPresent13)

/**
Whether or not to set ModelPresentationStyle automatically for instance, Default is [Class K_automaticallySetModalPresentationStyle].
@return BOOL
*/
@property (nonatomic, assign) BOOL K_automaticallySetModalPresentationStyle;

/**
 Whether or not to set ModelPresentationStyle automatically, Default is YES, but UIImagePickerController/UIAlertController is NO.
 @return BOOL
 */
+ (BOOL)K_automaticallySetModalPresentationStyle;


  •  

  •  

     

  • UIViewController+ERPPresent13.m

#import "UIViewController+ERPPresent13.h"

static const char *K_automaticallySetModalPresentationStyleKey;

@implementation UIViewController (ERPPresent13)
+ (void)load {
    Method originAddObserverMethod = class_getInstanceMethod(self, @selector(presentViewController:animated:completion:));
    Method swizzledAddObserverMethod = class_getInstanceMethod(self, @selector(K_presentViewController:animated:completion:));
method_exchangeImplementations(originAddObserverMethod, swizzledAddObserverMethod);



static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

            NSArray *selStringsArray = @[@"shouldAutorotate",@"supportedInterfaceOrientations",@"preferredInterfaceOrientationForPresentation"];


[selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
                NSString *mySelString = [@"sd_" stringByAppendingString:selString];

                Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
                Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(mySelString));
method_exchangeImplementations(originalMethod, myMethod);
}];
});


}

- (void)setK_automaticallySetModalPresentationStyle:(BOOL)K_automaticallySetModalPresentationStyle {
objc_setAssociatedObject(self, K_automaticallySetModalPresentationStyleKey, @(K_automaticallySetModalPresentationStyle), OBJC_ASSOCIATION_ASSIGN);
}

- (BOOL)K_automaticallySetModalPresentationStyle {
    id obj = objc_getAssociatedObject(self, K_automaticallySetModalPresentationStyleKey);
if (obj) {
return [obj boolValue];
}
return [self.class K_automaticallySetModalPresentationStyle];
}

+ (BOOL)K_automaticallySetModalPresentationStyle {
if ([self isKindOfClass:[UIImagePickerController class]] || [self isKindOfClass:[UIAlertController class]]) {
return NO;
}
return YES;
}



- (void)K_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if (@available(iOS 13.0, *)) {
if (viewControllerToPresent.K_automaticallySetModalPresentationStyle) {


            viewControllerToPresent.modalPresentationStyle = [QCTSession getModalPresentationStyleWith:viewControllerToPresent];



//            viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverFullScreen;// 1、后果:被怼了很惨,因为项目里有很多模态出来的VC是半透明,结果现在变成完全不透明,背景为黑色。2、 修复拜访记录日期控件PGDatePicker蒙版的问题:点击时间输入框,弹窗蒙版变成了空白

//                        viewControllerToPresent.modalPresentationStyle = UIModalPresentationAutomatic;// 1、后果:被怼了很惨,因为项目里有很多模态出来的VC是半透明,结果现在变成完全不透明,背景为黑色。2、 修复拜访记录日期控件PGDatePicker蒙版的问题:点击时间输入框,弹窗蒙版变成了空白

//            2、后遗症:因为把显示效果修改为:UIModalPresentationOverFullScreen;半透明,全屏覆盖的问题都得到完美解决。但是会引发一个新的问题:前一个页面的viewWillAppear:、viewDidAppear:也无法触发。例如:A   Present  B, 有时因为业务逻辑需要,必须在viewWillAppear, viewDidAppear里写一些代码,当B 调用dismiss方法的时候, A的这个两个方法不会触发,因此会有一些安全隐患。因此如果要求B 调用dismiss方法,A要执行viewWillAppear:、viewDidAppear:这个两个方法,这个时候要把B的modalPresentationStyle设置为:UIModalPresentationFullScreen;


//      3、      其他:如果要求 B既要半透明,dismiss时,A还要调用viewWillAppear:、viewDidAppear:。我的想法是在B 写一个block,在B调用dismiss之前,利用block回调A相关的业务逻辑代码。如果有其他更好的方法请告诉我。万分感谢!!



}
[self K_presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
// Fallback on earlier versions
[self K_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
  •  

  •  

1.2 定义app中模态展示的视图为全屏样式的VC

#pragma mark - ******** 定义app中模态展示的视图全屏的VC
/**

 对于【present 半屏】的新特性,至少有两种场景不适用:

 -  列表界面需要支持下拉刷新
 - 模态展示之后,需要特殊处理用户点击返回箭头事件。(比如当编辑商品价格的时候,用户编辑一般放弃不保存,而是点击下滑/返回,这个时候需要还原数据信息)

 */
- (NSMutableArray *)FullScreenClasss4NavRootVC{

if(_FullScreenClasss4NavRootVC == nil){

        _FullScreenClasss4NavRootVC = [NSMutableArray array];



[_FullScreenClasss4NavRootVC addObject:@"QCTBluetoothListViewController"];


[_FullScreenClasss4NavRootVC addObject:@"ERPMerchantUpdateEuipmentAliasViewController"];
[_FullScreenClasss4NavRootVC addObject:@"QCTSetStoreName4PrinterViewController"];

// 商品对规格信息界面
[_FullScreenClasss4NavRootVC addObject:@"QCTeditskuInfoViewController"];



}
return _FullScreenClasss4NavRootVC;

}

- (NSMutableArray *)FullScreenClasss{

if(_FullScreenClasss == nil){

        _FullScreenClasss = [NSMutableArray array];


[_FullScreenClasss addObject:@"PGDatePickManager"];

}
return _FullScreenClasss;

}

  •  

1.3 根据定义的规则,返回Modal风格类型

#pragma mark - ******** 根据定义的规则,返回Modal风格类型
+ (UIModalPresentationStyle)getModalPresentationStyleWith:(UIViewController*)viewControllerToPresent{





if([viewControllerToPresent isMemberOfClass:NSClassFromString(@"UISnapshotModalViewController") ]){



return UIModalPresentationOverFullScreen;


}


if(
[QCTSession.shareQCTSession.FullScreenClasss containsObject:NSStringFromClass(viewControllerToPresent.class)])


{




return UIModalPresentationFullScreen;


}



if([viewControllerToPresent isMemberOfClass:NSClassFromString(@"HWNavigationController")] ){


                                    HWNavigationController *nav = viewControllerToPresent;



if( [QCTSession.shareQCTSession.FullScreenClasss4NavRootVC containsObject:NSStringFromClass(nav.visibleViewController.class)]){

return UIModalPresentationFullScreen;



}








}


if (@available(iOS 13.0, *)) {
return UIModalPresentationAutomatic;
} else {
// Fallback on earlier versions

return UIModalPresentationFullScreen;

}



}

  •  

II、完整demo源码 see also
  • 【OS13的适配汇总:解决了IOS13的适配性问题】

 



这篇关于iOS13适配【灵活控制模态展示的视图样式】(全屏/下滑返回)文中提供完整demo源码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程