解决在自定义tabbar的时候出现双tabbar的问题
最近有个项目需要自定义tabbar,
我自定义tabbar的一个思路就是完全取代系统自带的tabbar,生成一个继承自UIview的customTabbar,将生成的customTabbar完全覆盖到tabbar上,为了让我们自己生成的tabbar也能使用系统的一些方法,我们需要将customTabbar添加到系统的tabbar上,这就是我的一个大概思路(后期再添加自定义的相关逻辑和代码)
在自定义tabbar的时候出现的问题,在iOS7以后tabbar做了一些修改,如果我们将customTabbar直接添加到系统的tabbar后,我们会发现,在显示的时候出现我们自己的tabbar和系统的tabbar这种效果当然使我们不需要的,怎么解决呢?我提供一个我的思路:我的做法是将系统tabbar生成的UItabbarButton从他的父视图上面移除,
[objc]view plaincopy
for(UIView*button inself.tabBar.subviews) {
if([buttonisKindOfClass:[LXQTabBarclass]]) {
NSLog(@"button == %@",button);
}else{
[buttonremoveFromSuperview];
}
}
这样就完美解决了,但是在后期使用中又发现一个问题,当我们dismiss或则popToViewController的时候,还是会出现系统的tabbarbutton,什么原因呢?我也不清楚,我大概想到可能和view里面的layoutSubviews这个方法有关,(希望有大神能讲解一下这一块的东西,谢谢),但是tabbarController没有这个方法,只有viewwilllayoutsubviews和ViewWilldidlayoutsubsiews这两个方法,最后将删除系统tabbarbutton的方法添加到了ViewWillLayoutSubviews这个方法里面就解决了这个问题
后记:
在更新iOS 10以后又重新出现以前的情况,一时不知道该怎么去解决,后面想了想,一直在外部去修改还不如去内部修改,因此想到了runtime来解决这个问题,通过runtime去修改系统的方法下面列出代码:
一、打印UITabbar系统方法:
[objc]view plaincopy
- (void)systemMethod{
unsignedintcount;
NSMutableArray*array = [NSMutableArrayarray];
Method*meths = class_copyMethodList([UITabBarclass], &count);
for(inti =0; i < count; i ++) {
Method meth = meths[i];
SELsel = method_getName(meth);
constcharchar*name = sel_getName(sel);
NSString*str = [NSStringstringWithFormat:@"-------------- > %s",name];
[arrayaddObject:str];
}
LOG(@"%@",array);
}
打印的结果:
[objc]view plaincopy
(
"-------------- > remove_layoutSubviews",
"-------------- > setDelegate:",
"-------------- > layoutSubviews",
"-------------- > _populateArchivedSubviews:",
"-------------- > hitTest:withEvent:",
"-------------- > _intrinsicSizeWithinSize:",
"-------------- > _contentHuggingDefault_isUsuallyFixedHeight",
"-------------- > sizeThatFits:",
"-------------- > traitCollectionDidChange:",
"-------------- > _backgroundView",
"-------------- > setSemanticContentAttribute:",
"-------------- > setTranslatesAutoresizingMaskIntoConstraints:",
"-------------- > touchesBegan:withEvent:",
"-------------- > touchesMoved:withEvent:",
"-------------- > touchesEnded:withEvent:",
"-------------- > touchesCancelled:withEvent:",
"-------------- > _setVisualAltitude:",
"-------------- > _setVisualAltitudeBias:",
"-------------- > isTranslucent",
"-------------- > isLocked",
"-------------- > didUpdateFocusInContext:withAnimationCoordinator:",
"-------------- > preferredFocusedItem",
"-------------- > setTintColor:",
"-------------- > _isEligibleForFocus",
"-------------- > canBecomeFocused",
"-------------- > removeConstraint:",
"-------------- > addConstraint:",
"-------------- > _didMoveFromWindow:toWindow:",
"-------------- > hitTest:forEvent:",
"-------------- > _didChangeFromIdiom:onScreen:traverseHierarchy:",
"-------------- > _subclassImplementsDrawRect",
"-------------- > backgroundImage",
"-------------- > shadowImage",
"-------------- > setShadowImage:",
"-------------- > _appearanceStorage",
"-------------- > _accessibilityButtonShapesParametersDidChange",
"-------------- > _effectiveBarTintColor",
"-------------- > setItems:animated:",
"-------------- > setLocked:",
"-------------- > setBarStyle:",
"-------------- > _hidesShadow",
"-------------- > _backdropViewLayerGroupName",
"-------------- > _setBackdropViewLayerGroupName:",
"-------------- > _shadowView",
"-------------- > _setBackgroundView:",
"-------------- > _shadowAlpha",
"-------------- > _setShadowAlpha:",
"-------------- > _disableBlurTinting",
"-------------- > _setDisableBlurTinting:",
"-------------- > setBarTintColor:",
"-------------- > _setHidesShadow:",
"-------------- > barStyle",
"-------------- > setTranslucent:",
"-------------- > barTintColor",
"-------------- > _accessoryView",
"-------------- > _isTranslucent",
"-------------- > _setBarOrientation:",
"-------------- > _setAccessoryView:",
"-------------- > setSelectedItem:",
"-------------- > _setPreferredFocusHeading:",
"-------------- > _setFocusedItemHightlightShouldBeVisible:",
"-------------- > _setHiddenAwaitingFocus:",
"-------------- > beginCustomizingItems:",
"-------------- > isCustomizing",
"-------------- > setBackgroundImage:",
"-------------- > _sendAction:withEvent:",
"-------------- > _barMetrics",
"-------------- > _imageStyle",
"-------------- > _setBarMetrics:",
"-------------- > _setImageStyle:",
"-------------- > selectionIndicatorImage",
"-------------- > selectedImageTintColor",
"-------------- > _effectiveUnselectedTabTintColorConsideringView:",
"-------------- > _buttonDown:",
"-------------- > _buttonUp:",
"-------------- > _buttonCancel:",
"-------------- > _showsHighlightedState",
"-------------- > _setShowsHighlightedState:",
"-------------- > _scrollsItems",
"-------------- > itemPositioning",
"-------------- > itemWidth",
"-------------- > itemSpacing",
"-------------- > _configureItems:",
"-------------- > _setBackgroundNeedsUpdate:",
"-------------- > _blurEnabled",
"-------------- > _preferredFocusHeading",
"-------------- > selectedItem",
"-------------- > _focusedItemHighlightShouldBeVisible",
"-------------- > _setBlurEnabled:",
"-------------- > setSelectionIndicatorImage:",
"-------------- > setSelectedImageTintColor:",
"-------------- > _configureTabBarReplacingItem:withNewItem:swapping:",
"-------------- > _positionAllItems",
"-------------- > setItemWidth:",
"-------------- > setItemSpacing:",
"-------------- > _setScrollsItems:",
"-------------- > setItemPositioning:",
"-------------- > _accessibilityButtonShapesEnabledDidChangeNotification:",
"-------------- > setUnselectedItemTintColor:",
"-------------- > _doCommonTabBarInit",
"-------------- > _effectiveBarOrientation",
"-------------- > _updateBackgroundColorForTraitCollection:",
"-------------- > _customizeWithAvailableItems:",
"-------------- > _dismissCustomizeSheet:",
"-------------- > _updateTintedImages:selected:",
"-------------- > _effectiveBarTintColorDidChange",
"-------------- > unselectedItemTintColor",
"-------------- > _effectiveUnselectedTintColor",
"-------------- > _isHiddenAwaitingFocus",
"-------------- > _buttonDownDelayed:",
"-------------- > _adjustButtonSelection:",
"-------------- > _customizeDoneButtonAction:",
"-------------- > _totalDimensionForItems:spacing:dimension:scaleFactor:",
"-------------- > _setBackgroundImage:",
"-------------- > _setSelectionIndicatorImage:",
"-------------- > _setLabelFont:",
"-------------- > _setLabelTextColor:selectedTextColor:",
"-------------- > _setLabelShadowColor:",
"-------------- > _setLabelShadowOffset:",
"-------------- > _setVibrantLabels:",
"-------------- > _vibrantLabels",
"-------------- > _nextSelectionSlideDuration",
"-------------- > _setNextSelectionSlideDuration:",
"-------------- > _backgroundNeedsUpdate",
"-------------- > _setTabBarSizing:",
"-------------- > _setTabButtonWidth:",
"-------------- > _tabButtonWidth",
"-------------- > _setInterTabButtonSpacing:",
"-------------- > _interTabButtonSpacing",
"-------------- > _barOrientation",
"-------------- > endCustomizingAnimated:",
"-------------- > _makeCurrentButtonFirstResponder",
"-------------- > _setDividerImage:forLeftButtonState:rightButtonState:",
"-------------- > _dividerImageForLeftButtonState:rightButtonState:",
"-------------- > _pendingFocusAction",
"-------------- > _setPendingFocusAction:",
"-------------- > _focusedTabBarItem",
"-------------- > _tabBarFinishedAnimating",
"-------------- > dismissCustomizeSheet:",
"-------------- > _scaleFactorForItems:spacing:dimension:maxWidth:",
"-------------- > _updateTabBarItemView:",
"-------------- > _tabBarSizing",
"-------------- > isElementAccessibilityExposedToInterfaceBuilder",
"-------------- > _autolayoutSpacingAtEdge:inContainer:",
"-------------- > _autolayoutSpacingAtEdge:nextToNeighbor:",
"-------------- > _hasCustomAutolayoutNeighborSpacing",
"-------------- > encodeWithCoder:",
"-------------- > initWithCoder:",
"-------------- > delegate",
"-------------- > setBounds:",
"-------------- > .cxx_destruct",
"-------------- > dealloc",
"-------------- > initWithFrame:",
"-------------- > setFrame:",
"-------------- > items",
"-------------- > setItems:",
"-------------- > drawRect:"
)
我接触iOS的时间也不长,不能从这对堆结果中去找到具体设置tabbarbutton的方法,但是我知道layoutSubviews是布局子视图的方法,然后就用runtime替换掉UItabbar中的layoutSubviews方法,在布局子视图的时候将系统自带的UItabbarbutton给移除掉,贴代码:
这段代码是写在UItabbar的分类中的:
[objc]view plaincopy
+ (void)load{
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SELsystemSel =@selector(layoutSubviews);
SELlxqSel =@selector(remove_layoutSubviews);
Method systemMethod = class_getInstanceMethod([selfclass], systemSel);
Method lxqMethod = class_getInstanceMethod([selfclass], lxqSel);
BOOLisAdd = class_addMethod(self, systemSel, method_getImplementation(lxqMethod), method_getTypeEncoding(lxqMethod));
if(isAdd) {
class_replaceMethod(self, lxqSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
}else{
method_exchangeImplementations(systemMethod, lxqMethod);
}
});
}
- (void)remove_layoutSubviews{
NSArray*subviews =self.subviews;
for(UIView*subview in subviews) {
if([subviewisKindOfClass:[LXQTabBarclass]]) {
}else{
[subviewremoveFromSuperview];
}
}
}
这样就完美解决了iOS10 以及以前系统的问题了,不过就是不知道这样做了之后会不会出现审核不通过的问题!
原文链接 :http://blog.csdn.net/lixingqiao01/article/details/51819358