cdts/xdts-ios 3/TreeHole/Code/Base/PYBaseViewController.m
2023-07-27 09:20:00 +08:00

510 lines
16 KiB
Objective-C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// PYBaseViewController.m
// Food
//
// Created by ko1o on 2019/7/16.
// Copyright © 2019年 ko1o. All rights reserved.
//
#import "PYBaseViewController.h"
#import "UIViewController+BXYStatefulViewController.h"
#import "UIImage+Extender.h"
#import <IQKeyboardManager.h>
#import "UINavigationController+FDFullscreenPopGesture.h"
@interface PYBaseViewController ()<MTStatefulBaseViewDelegate>
@property (nonatomic, strong) UIImage *backupNavgationBarShadowImage;
@property (nonatomic, assign) BOOL hasLoadedStateful;
@property (nonatomic, weak) UIViewController * mt_previousVC;
@property (nonatomic, assign) BOOL isViewAppear;
@property (nonatomic, assign) BOOL isTrackPageEnded;
@property (nonatomic, assign) BOOL stopLoading;
@property (nonatomic, strong) UIView *maskView;
@end
@implementation PYBaseViewController
//MARK: - QM
- (instancetype)init {
if (self = [super init]) {
if ([QMUIHelper.visibleViewController.navigationController isKindOfClass:NSClassFromString(@"THNavigationController")]) {
//兼容QMUIKit
self.hidesBottomBarWhenPushed = YES;
}
}
return self;
}
//MARK: - Other
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.extendedLayoutIncludesOpaqueBars = YES;
if (![self isSupportFullScreenLayout]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
// self.automaticallyAdjustsScrollViewInsets = NO;
}
self.mt_translucent = NO;
self.mt_nav_barTintColor = [UIColor whiteColor];
self.mt_nav_tintColor = [UIColor blackColor];
self.mt_barStyle = UIBarStyleDefault;
}
return self;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
if (self.mt_barStyle == UIBarStyleBlack) {
return UIStatusBarStyleLightContent;
}
return UIStatusBarStyleLightContent;
}
- (BOOL)isSupportContentScrollView
{
return NO;
}
- (BOOL)isSupportShare
{
return NO;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.bxy_loadingView.centerY = self.bxy_errorView.centerY = self.bxy_emptyView.centerY = self.view.height * 0.5;
self.bxy_emptyView.userInteractionEnabled = NO;
self.bxy_errorView.userInteractionEnabled = NO;
}
- (BOOL)canBack {
return YES;
}
- (BOOL)fd_interactivePopDisabled {
if (![self canBack]) {
return YES;
}
if ([MTAlertView hasAlertViewShowing]) { // 当前显示AlertView禁用
return YES;
}
return _fd_interactivePopDisabled;
}
- (void)viewDidLoad {
[super viewDidLoad];
//配置页面状态view
if ([self mt_shouldSetupStateful] && self.hasLoadedStateful) {
[self bxy_setupInitialViewState];
}
self.view.backgroundColor = BG_COLOR;
self.maskView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.maskView.backgroundColor = UIColor.blackColor;
WeakSelf(self);
[self.maskView addTapWithAction:^{
[weakself.view endEditing:YES];
}];
if ([self mt_shouldSetupStateful]) {
self.bxy_loadingView = [[MTStatefulBaseView alloc] initWithFrame:CGRectZero type:MTStatefulViewTypeLoading delegate:self];
self.bxy_emptyView = [[MTStatefulBaseView alloc] initWithFrame:CGRectZero type:MTStatefulViewTypeEmpty delegate:self];
self.bxy_errorView = [[MTStatefulBaseView alloc] initWithFrame:CGRectZero type:MTStatefulViewTypeError delegate:self];
}
if (self.preferredStatusBarStyle == UIStatusBarStyleLightContent) {
self.mt_barStyle = UIBarStyleBlack;
} else {
self.mt_barStyle = UIBarStyleDefault;
}
if ([self isSupportContentScrollView]) {
self.contentScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.contentScrollView.backgroundColor = [UIColor clearColor];
self.contentScrollView.showsVerticalScrollIndicator = YES;
self.contentScrollView.alwaysBounceVertical = YES;
[self.view addSubview:self.contentScrollView];
self.contentScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
// if ([[[UIDevice currentDevice] systemVersion] floatValue] <= 11.0) {
// self.contentScrollView.y = NAVIGATION_BAR_HEIGHT;
// self.contentScrollView.height = self.view.height - self.contentScrollView.y;
// }
}
if (self.navigationController.childViewControllers.count > 1) {
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:ImageNamed(@"TH_back_black") style:UIBarButtonItemStyleDone target:self action:@selector(back)];
self.navigationItem.leftBarButtonItem = backItem;
}
if (![self canBack]) {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:[UIView new]];
}
[self.navigationController setModalPresentationStyle:UIModalPresentationFullScreen];
self.mt_prefersNavigationBarShadowHidden = YES;
if ([self mt_nagationBarTransparent]) {
self.mt_translucent = YES;
self.extendedLayoutIncludesOpaqueBars = YES;
}
if ([self isSupportShare]) {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:ImageNamed(@"share") style:UIBarButtonItemStyleDone target:self action:@selector(shareDidClick)];
}
// if (self.mt_prefersNavigationBarShadowHidden) {
// self.navigationController.navigationBar.shadowImage = [UIImage new];
// }
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if ([textField.inputView isKindOfClass:NSClassFromString(@"MTPickerView")]) {
textField.tintColor = UIColor.clearColor;
[self showMaskView];
} else {
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
}
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if ([textField.inputView isKindOfClass:NSClassFromString(@"MTPickerView")]) {
[self hideMaskView];
}
return YES;
}
- (void)showMaskView
{
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
[self.view.window addSubview:self.maskView];
self.maskView.alpha = 0.0;
[self.view.window bringSubviewToFront:self.maskView];
[UIView animateWithDuration:0.25 animations:^{
self.maskView.alpha = 0.3;
}];
}
- (void)hideMaskView
{
[UIView animateWithDuration:0.25 animations:^{
self.maskView.alpha = 0.0;
} completion:^(BOOL finished) {
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
}];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.view endEditing:animated];
self.isViewAppear = NO;
}
- (void)back {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES];
}
- (BOOL)mt_nagationBarTransparent
{
if (self.title.length > 0) { // 有文本
return NO;
}
return _mt_nagationBarTransparent;
}
- (BOOL)isSupportFullScreenLayout
{
return YES;
}
- (UIModalPresentationStyle)modalPresentationStyle {
return UIModalPresentationFullScreen;
}
//配置是否显示loading empty error 页面提示
- (BOOL)mt_shouldSetupStateful
{
return YES;
}
- (NSString *)emptyTips {
return @"空空无也~";
}
- (BOOL)mt_hasContentForStateful
{
return self.stopLoading;
}
- (void)mt_startStatefulLoading:(BOOL)animated
{
if ([self mt_shouldSetupStateful]) {
self.hasLoadedStateful = YES;
dispatch_async(dispatch_get_main_queue(), ^{
[self bxy_startLoading:animated completion:^{
;
}];
});
}
}
- (void)mt_endStatefulLoading:(BOOL)animated error:(NSError *)error
{
if ([self mt_shouldSetupStateful]) {
[self bxy_endLoading:animated error:error completion:^{
;
}];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (![self isNavigationBarHidden]) {
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
[self mt_applyAppearanceToNavigationBar:self.navigationController.navigationBar];
}
- (BOOL)enableAutoToolbar {
return YES;
}
- (BOOL)isNavigationBarHidden {
return NO;
}
- (void)viewDidAppear:(BOOL)animated
{
//当前页面的源VC往前回溯一级
UIViewController *mt_previousViewController;
NSInteger index = [self.navigationController.viewControllers indexOfObject:self];
if (index != NSNotFound && index >= 1) {
mt_previousViewController = [self.navigationController.viewControllers objectAtIndex:index -1];
}
if (self.parentViewController && !mt_previousViewController) { //被其他vc 承载
UIViewController * parent = self.parentViewController;
index = [parent.navigationController.viewControllers indexOfObject:parent];
if (index != NSNotFound && index >= 1) {
mt_previousViewController = [parent.navigationController.viewControllers objectAtIndex:index -1];
}
}
if (!mt_previousViewController) {
mt_previousViewController = self.presentingViewController;
}
self.mt_previousVC = mt_previousViewController;
[super viewDidAppear:animated];
self.isViewAppear = YES;
[self.navigationController setNavigationBarHidden:[self isNavigationBarHidden] animated:NO];
[IQKeyboardManager sharedManager].enableAutoToolbar = [self enableAutoToolbar];
[self mt_applyAppearanceToNavigationBar:self.navigationController.navigationBar];
}
- (void)startLoading
{
self.stopLoading = NO;
[self mt_startStatefulLoading:NO];
}
- (void)endLoading:(NSError *)error
{
self.stopLoading = YES;
[self mt_endStatefulLoading:NO error:error];
}
#pragma mark - StatefulViewControllerProtocol
/**
* Return true if content is available in your controller.
*
* - returns: true if there is content available in your controller.
*/
- (BOOL)hasContent
{
return [self mt_hasContentForStateful];
}
/**
* This method is called if an error occurred, but `hasContent` returned true.
* You would typically display an unobstrusive error message that is easily dismissable
* for the user to continue browsing content.
*
* - parameter error: The error that occurred
*/
- (void)handleErrorWhenContentAvailable:(NSError *)error
{
}
#pragma mark - MTStatefulBaseViewDelegate
- (MTStatefulConfigItem *)statefulConfigItemForStatefulViewType:(MTStatefulViewType)statefulViewType
{
MTStatefulConfigItem *item = [MTStatefulConfigItem new];
WeakSelf(self);
if (statefulViewType == MTStatefulViewTypeEmpty) {
MTStatefulConfigItem *item = [[MTStatefulConfigItem alloc] init];
item.statefulTitle = [self emptyTips];
return item;
}
// else
// if (statefulViewType == MTStatefulViewTypeError) {
// StrongSelf(self);
// MTStatefulConfigItem *item = [[MTStatefulConfigItem alloc] init];
// item.statefulTitle = @"哎哟!网络异常,请稍后…";
// item.shouldShowErrorRefresh = YES;
// item.didClickedRefreshBlock = self.didClickedRefreshBlock;
// return item;
// }
item.shouldShowErrorRefresh = NO;
return item;
}
@end
@interface UIViewControllerMTAppearance : NSObject
@property (nonatomic, assign) BOOL mt_translucent;
@property (nonatomic, assign) BOOL mt_prefersNavigationBarShadowHidden;
@property (nonatomic, strong) UIColor * mt_nav_barTintColor;
@property (nonatomic, strong) UIColor * mt_navbarBackgroundImageColor;
@property (nonatomic, strong) UIColor * mt_nav_tintColor;
@property (nonatomic, strong) NSDictionary * mt_titleTextAttributes;
@property (nonatomic, assign) UIBarStyle mt_barStyle;
@property (nonatomic, strong) UIImage * mt_navbarBackgroundImage;
@end
@implementation UIViewControllerMTAppearance
@end
@interface UIViewController (MTAppearanceInner)
@property (nonatomic, strong) UIViewControllerMTAppearance *mtAppearance;
@end
@implementation UIViewController (MTAppearance)
@dynamic mt_translucent;
@dynamic mt_prefersNavigationBarShadowHidden;
@dynamic mt_nav_barTintColor;
@dynamic mt_navbarBackgroundImageColor;
@dynamic mt_nav_tintColor;
@dynamic mt_titleTextAttributes;
@dynamic mt_navbarBackgroundImage;
- (BOOL)mt_translucent
{
return self.mtAppearance.mt_translucent;
}
- (void)setMt_translucent:(BOOL)mt_translucent
{
self.mtAppearance.mt_translucent = mt_translucent;
}
- (UIViewControllerMTAppearance *)mtAppearance
{
UIViewControllerMTAppearance *mtAppearance = objc_getAssociatedObject(self, _cmd);
if (!mtAppearance) {
mtAppearance = [UIViewControllerMTAppearance new];
objc_setAssociatedObject(self, _cmd, mtAppearance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return mtAppearance;
}
- (id)forwardingTargetForSelector:(SEL)sel
{
if ([self.mtAppearance respondsToSelector:sel]) {
return self.mtAppearance;
}
return nil;
}
- (void)mt_applyAppearanceToNavigationBar:(UINavigationBar *) navigationBar
{
UIViewController * vc = self;
navigationBar.translucent = vc.mt_translucent;
UIImage *barBackgroundImage = [UIImage new];
if (vc.mt_navbarBackgroundImageColor) {
UIImage *barImage = vc.mt_navbarBackgroundImageColor == [UIColor clearColor] ? [UIImage new] : [UIImage imageWithColor:vc.mt_navbarBackgroundImageColor size:CGSizeMake(10, 10)] ;
barBackgroundImage = barImage;
}
[navigationBar setBackgroundImage:barBackgroundImage forBarMetrics:UIBarMetricsDefault];
if (vc.mt_navbarBackgroundImage) {
[navigationBar setBackgroundImage:vc.mt_navbarBackgroundImage forBarMetrics:UIBarMetricsDefault];
}
vc.mt_nav_barTintColor = [self preferredStatusBarStyle] == UIStatusBarStyleLightContent ? COLOR_WITH_RGB(0x15112D) : [UIColor whiteColor];
navigationBar.barStyle = vc.mt_barStyle;
navigationBar.barTintColor = vc.mt_nav_barTintColor;
UIColor *tintColor = [self preferredStatusBarStyle] == UIStatusBarStyleLightContent ? UIColor.whiteColor : TITLE_COLOR;
navigationBar.tintColor = tintColor;
navigationBar.titleTextAttributes = vc.mt_titleTextAttributes ?: @{NSFontAttributeName : MT_FONT_MEDIUM_SIZE(15), NSForegroundColorAttributeName : tintColor};
navigationBar.shadowImage = [vc mt_prefersNavigationBarShadowHidden] ? [UIImage new] : nil ;
// navigationBar.shadowImage = [UIImage imageWithColor:[UIColor colorWithWhite:1.0 alpha:0.1] size:CGSizeMake(SCREEN_WIDTH, 0.5)];
if (@available(iOS 15.0, *)) {
UINavigationBarAppearance *barApp = [UINavigationBarAppearance new];
barApp.backgroundColor = navigationBar.barTintColor;
barApp.titleTextAttributes = navigationBar.titleTextAttributes;
barApp.shadowImage = navigationBar.shadowImage;
barApp.shadowColor = [UIColor clearColor];
barApp.backgroundImage = barBackgroundImage;
self.navigationController.navigationBar.translucent = [self mt_translucent];
if ([self mt_translucent]) { // 设置透明导航栏
[barApp configureWithTransparentBackground];
} else {
barApp.backgroundImage = [UIImage imageWithColor:navigationBar.barTintColor size:navigationBar.size];
}
self.navigationController.navigationBar.scrollEdgeAppearance = barApp;
self.navigationController.navigationBar.standardAppearance = barApp;
}
}
@end