一、关于iPhone X适配
//是否是iPhone X
#define kIsiPhoneX (UIScreen.mainScreen.bounds.size.height == 812 || UIScreen.mainScreen.bounds.size.width == 812)
//状态栏高度
#define kStatusBarHeight (kIsiPhoneX?44:20)
//底部增加高度
#define kBottomBarAddHeight (kIsiPhoneX?kAVMBottomBarAddHeight_iPhoneX:0)
//底部tabbar iPhoneX 增加高度 34
static CGFloat kBottomBarAddHeight_iPhoneX = 34.f;
//设置iPhone X的scrollView 底部扩展34
#define kUIScrollViewiPhoneX(scrollView) if (kIsiPhoneX) {\
scrollView.contentInset = UIEdgeInsetsMake(0, 0, kAVMBottomBarAddHeight_iPhoneX, 0);\
}
复制代码
二、关于iOS 11部分适配
1、 UIScrollView 有偏移时解决: 在iOS 11之前ViewController viewDidLoad设置
if (!IsiOS11AndLater) {
self.automaticallyAdjustsScrollViewInsets = NO;
}
复制代码
在iOS 11 使用分类一步解决,设置
.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever
@implementation UIScrollView (TTiOS11Adjust)
+ (void)load {
Method m0_original = class_getInstanceMethod([self class], @selector(initWithFrame:));
Method m0_new = class_getInstanceMethod([self class], @selector(tt_iOS11_initWithFrame:));
method_exchangeImplementations(m0_original, m0_new);
Method m1_original = class_getInstanceMethod([self class], @selector(awakeFromNib));
Method m1_new = class_getInstanceMethod([self class], @selector(tt_iOS11_awakeFromNib));
method_exchangeImplementations(m1_original, m1_new);
}
- (instancetype)tt_iOS11_initWithFrame:(CGRect)frame {
if (![self isKindOfClass:[UIScrollView class]]) {
return self;
}
[self tt_iOS11_initWithFrame:frame];
#ifdef __IPHONE_11_0
if ([self respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
// Fallback on earlier versions
}
}
#endif
return self;
}
- (void)tt_iOS11_awakeFromNib {
if (![self isKindOfClass:[UIScrollView class]]) {
return ;
}
[self tt_iOS11_awakeFromNib];
#ifdef __IPHONE_11_0
if ([self respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
// Fallback on earlier versions
}
}
#endif
}
复制代码
2、 修改UINavigationBar上自定义按钮的可点击区域
自定义按钮继承UIButton
实现- beginTrackingWithTouch: withEvent:
判断点击范围
@interface TTBaseNavigationItemBarButton : UIButton
@end
@implementation TTBaseNavigationItemBarButton
{
CFAbsoluteTime _hitTime;
}
///修正bar点击区域太大的问题
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event {
//不连续点击
CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
if ((currentTime - _hitTime) < 1 ) {
return NO;
}
_hitTime = currentTime;
BOOL beginTrack = [super beginTrackingWithTouch:touch withEvent:event];
CGPoint touchPoint = [touch locationInView:self];
if (beginTrack) {
if (IsiOS11AndLater) {
if ( touchPoint.y > 38 || (!self.isLeft && touchPoint.x < 5) || (self.isLeft && touchPoint.x > (self.frame.size.width -10))) {
return NO;
}
}else {
if ( touchPoint.y > 38 || (!self.isLeft && touchPoint.x < -1) || (self.isLeft && touchPoint.x > (self.frame.size.width +5))) {
return NO;
}
}
if (touchPoint.y > 38) {
return NO;
}
}else {
}
return beginTrack;
}
@end
复制代码
iOS 11之后UINavigationBar层级结构发生了改变,不会继续直接走UIButton
的- beginTrackingWithTouch: withEvent:
,所以折中处理:当点击UINavigationBar上的按钮时手动调用- beginTrackingWithTouch: withEvent:
方法。实现方法如下:
@implementation UIView (TTExtensioniOS11)
+ (void)load {
Method originalMethod = class_getInstanceMethod([self class], @selector(hitTest:withEvent:));
Method swizzleMethod = class_getInstanceMethod([self class], @selector(bm_hitTest:withEvent:));
BOOL didAddMethod = class_addMethod([self class], @selector(bm_hitTest:withEvent:), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
if (didAddMethod) {
class_replaceMethod([self class], @selector(hitTest:withEvent:), method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod));
} else {
method_exchangeImplementations(originalMethod, swizzleMethod);
}
}
- (UIView *)bm_hitTest:(CGPoint)point withEvent:(UIEvent *)event {
__block UIView *hitView = nil;
if (IsiOS11AndLater) {
if ([NSStringFromClass([self class]) isEqualToString: @"_UINavigationBarContentView"]) {
[self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull tobj, NSUInteger tidx, BOOL * _Nonnull tstop) {
if ([tobj isKindOfClass:NSClassFromString(@"_UIButtonBarStackView")]) {
if (CGRectContainsPoint(CGRectInset(tobj.frame, -16, 0), point)) {
[tobj.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull ttobj, NSUInteger ttidx, BOOL * _Nonnull ttstop) {
if ([ttobj isKindOfClass:NSClassFromString(@"_UITAMICAdaptorView")]) {
[ttobj.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull tttobj, NSUInteger tttidx, BOOL * _Nonnull tttstop) {
if ([tttobj isKindOfClass:NSClassFromString(@"TTBaseNavigationItemBarButton")]) {
hitView = tttobj;
*tttstop = YES;
}
}];
}
}];
}
}
}];
}
}
if (!hitView) {
hitView = [self bm_hitTest: point withEvent: event];
}
return hitView;
}
@end
复制代码