有关 在self.navigationItem.titleView 中增加视图的问题

文章探讨了在iOS开发中遇到的一个问题:当从一个页面导航到另一个页面时,自定义的UISegmentedControl会意外地从父视图移除,导致badge视图丢失。通过分析原因并提供解决方案,文章提出使用`[self.navigationItem.titleView addSubview:segmentedControl];`而非默认方式来避免此类问题。
我们通常都是直接这样使用的
    NSLog(@"self.navigationItem.titleView= %@",self.navigationItem.titleView);
    
NSArray *subviews = self.navigationItem.titleView.subviews;
    
NSLog(@"self.navigationItem.titleView.subviews= %@",subviews);
    
segmentedControl = [[MESegmentedControl alloc ]initWithItems:@[@"通知",@"纸条",@"邮件"]];
    
segmentedControl.frame = CGRectMake(0019028);
    
segmentedControl.backgroundColor = [UIColor clearColor];
    self.navigationItem.titleView = segmentedControl;

不过这样似乎有一个问题,当我们导航到下一级时候,这个segmentedControl 会被调用removeFromSuperview ,一般情况下可能没有问题,但是在一些极端情况下这个就有问题了,如题,我们上面是给UISegmentedControl  做的一个子类,它可以有badge,这个badge是加在该类的superview上的,并且在类中我们重载了此方法
-(void)removeFromSuperview
{
    
if (_badgeView) [_badgeView removeFromSuperview];
    [
super removeFromSuperview];
}

我们原来是在上面增加了badge视图,可是现在,导航进入了下一级,这个badge视图就消失了,这很显然不是我们想要的


进一步观察了 故事板中,


从中我们可以看出,在故事板中,我们给navigationItem 增加一个视图,都是采用 增加到子视图的模式,并不是采用
[self.navigationItem.titleView addSubview:segmentedControl]; 这种方式的



打印一下log,我们也可以看出是这样的
self.navigationItem.titleView= <UIView: 0x8bdca20; frame = (8 5.5; 304 33); autoresize = RM+BM; layer = <CALayer: 0x8bdcc60>>
2013-12-10 17:00:59.578 MESegmentedControl[94933:70b] 
self.navigationItem.titleView.subviews= (
    "<UISegmentedControl: 0x8bdccf0; frame = (20 3; 264 29); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8bdce80>>



综合上诉结论,我么最好是使用[self.navigationItem.titleView addSubview:segmentedControl]; 这种方式的
这种方式,在导航到下一级的时候,并不会被调用 removeFromSuperview
补充,这种情况下,被removeFromSuperview的只是那个self.navigationItem.titleView ,而不是我们的segmentedControl,如果我们没有 self.navigationItem.titleView,那首先还是要先生成一个UIView赋给self.navigationItem.titleView
private func handleViewWillAppear() { updateTabNamesAfterRelogin() navigationController?.navigationBar.barStyle = .default if isFirst { isFirst = false if appContext.isVmsLogin && !showLocalDeviceOnly && isDeviceListOld { reqSingleSiteInfoCode = appContext.requestSingVmsSiteInfo(bySiteId: self.currentSiteInfo?.siteId ?? 0) } } if needVmsRefresh && appContext.isVmsLogin && !showLocalDeviceOnly { needVmsRefresh = false if isDeviceListOld { reqSingleSiteInfoCode = appContext.requestSingVmsSiteInfo(bySiteId: self.currentSiteInfo?.siteId ?? 0) } if let vc = self.pageController.viewControllers?.first as? OnlineDeviceListViewController { vc.forceRefresh() } } // TODO: 替换文案 localDeviceCountLabel.text = String(format: LocalizedString(key: deviceListNumberOfDevices), localDeviceCount) LocalDeviceViewHeight.constant = CGFloat(0) localDeviceView.isHidden = true if !appContext.isLogin { //未登录 if showLocalDeviceOnly { if localDeviceCount == 0 { self.navigationItem.rightBarButtonItems = [addButtonmItem] } else { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } moreSiteButton.isHidden = localDeviceCount == 0 tabBarCollectionView.isHidden = localDeviceCount == 0 } else { //如果未登录则左边按钮不显示 self.navigationItem.leftBarButtonItems = [mineButtonItem] //右边显示所有按钮 self.navigationItem.rightBarButtonItems = [addButtonmItem,negativeButtonItem] tabBarCollectionView.isHidden = true } scrollView.setContentOffset(CGPoint(x: 0, y: 62), animated: false) } else { //如果登录了则左边按钮显示 if showLocalDeviceOnly { moreSiteButton.isHidden = localDeviceCount == 0 tabBarCollectionView.isHidden = localDeviceCount == 0 if localDeviceCount == 0 { self.navigationItem.rightBarButtonItems = [addButtonmItem] } else { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem, searchItem] } removeLeftBarButtonItem() addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) } else { moreSiteButton.isHidden = false tabBarCollectionView.isHidden = false if appContext.isVmsLogin { // 登录状态VMS if isDeviceListOld { removeLeftBarButtonItem() addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) self.navigationItem.rightBarButtonItems = [searchItem, changeDisplayTypeItem] } else { // tab新版VMS不能滚动 tabBarCollectionView.isScrollEnabled = true // addLeftBarButtonItem() if appContext.loginType == .cloud { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } else { self.navigationItem.rightBarButtonItems = [] } } } else { // 登录状态个人版 reqVmsOrgListCode = appContext.requestVMSOrganizationList(withUsername: appContext.accountUsername, password: appContext.accountPassword ?? "") // removeLeftBarButtonItem() // if let hasVms = UserDefaults.standard.object(forKey: kHasCloudVMSOrganization) as? Bool, hasVms { // addLeftBarButtonItem() // } self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } } scrollView.setContentOffset(CGPoint(x: 0, y: 62), animated: false) } if !appContext.isLogin && !showLocalDeviceOnly{ showEmpty() return } else if firstAppear { firstAppear = false restore() } else if shouldRecreate { shouldRecreate = false reload() } //评分引导 self.isNeedEvaluation() // 当tab栏个数等于1的时候禁止左右滑动 for view in pageController.view.subviews { if let subView = view as? UIScrollView { subView.isScrollEnabled = tabNames.count > 1 // 优先处理屏幕边缘滑动手势 if let gestureRecognizers = self.view.gestureRecognizers { for recognizer in gestureRecognizers { if recognizer is UIScreenEdgePanGestureRecognizer { subView.panGestureRecognizer.require(toFail: recognizer) } } } } } registerCallback() if !appContext.isLocalVMSLogin { addTitleView() } else if !isDeviceListOld && !showLocalDeviceOnly { let titleLabel = UILabel() titleLabel.textAlignment = .natural titleLabel.font = .boldProjectFont(ofSize: 22) titleLabel.textColor = .tpbTextPrimary titleLabel.text = appContext.isVmsLogin ? appContext.accountInfo.currentVmsName : LocalizedString(key: accountMyVIGI) let titleItem = UIBarButtonItem.init(customView: titleLabel) navigationItem.leftBarButtonItems = [titleItem] } guard let vc = self.pageController.viewControllers?.first as? OnlineDeviceListViewController else { commonLoad() return } vc.deviceOnlineStatus = currentDeviceOnlineType } 这部分呢
11-18
再重新根据我目前写的弄一下,中间那些逻辑复杂的可以不分的那么仔细 override func viewDidLoad() { super.viewDidLoad() // step1:基础外观 setupAppearance() // step2:数据加载触发(如请求组织列表) loadInitialDataIfNeeded() // step3:注册通知监听 setupNotifications() self.addRightBarButtonItem() self.addLeftBarButtonItem() if !isDeviceListOld { tabNames = appContext.isVmsLogin ? [ LocalizedString(key: deviceListAllDevices)] : [LocalizedString(key: deviceCollectFavorites), LocalizedString(key: deviceListAllDevices)] } if appContext.isVmsLogin { if !showLocalDeviceOnly { if !isDeviceListOld { //支持收藏,allDeviceTabIndex、siteDeviceTabIndex可以设置为1、2 if !DeviceListMasterViewController.isSupportVMSFavorite { //不支持收藏 collectDviceTabIndex = -1 allDeviceTabIndex = 0 siteDeviceTabIndex = 1 } else { collectDviceTabIndex = 0 allDeviceTabIndex = 1 siteDeviceTabIndex = 2 } tabBarContainerTopConstraint.constant = 10 moreSiteButton.setImage(TPImageLiteral("devicelist_menu_more"), for: .normal) moreSiteButton.addTarget(self, action: #selector(menuButtonClicked(_:)), for: .touchUpInside) moreSiteButton.backgroundColor = .clear tabCollectionHeightConstant.constant = 30 tabNames.removeAll() if DeviceListMasterViewController.isSupportVMSFavorite { tabNames.append(LocalizedString(key: deviceCollectFavorites)) } tabNames.append(LocalizedString(key: deviceListAllDevices)) selectedTabType = UserDefaults.standard.deviceListSelectedType ?? .all if DeviceListMasterViewController.isSupportVMSFavorite { selectedTabIndex = selectedTabType.rawValue } selectedSiteInfo = DeviceListMasterViewController.getSavedSelectedSiteInfo() if selectedSiteInfo != nil && selectedSiteInfo?.siteId != 0 && selectedSiteInfo?.siteName != "" { tabNames.append(selectedSiteInfo?.siteName ?? "") if selectedTabType == .site { selectedTabIndex = siteDeviceTabIndex } } else { tabNames.append(LocalizedString(key: commonChoose)) } } else { addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) //新版本vms才支持收藏,allDeviceTabIndex、siteDeviceTabIndex设置为以前的0、1 collectDviceTabIndex = -1 allDeviceTabIndex = 0 siteDeviceTabIndex = 1 tabCollectionHeightConstant.constant = 52 moreSiteButton.setImage(TPImageLiteral("vms_site_more"), for: .normal) moreSiteButton.addTarget(self, action: #selector(moreSiteButtonClick), for: .touchUpInside) moreSiteButton.backgroundColor = .clear self.titleLabel.text = currentSiteInfo?.siteName ?? "" let titleView = UIView() titleView.addSubview(self.titleLabel) NSLayoutConstraint.init(item: self.titleLabel, attribute: .centerY, relatedBy: .equal, toItem: titleView, attribute: .centerY, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint.init(item: self.titleLabel, attribute: .leading, relatedBy: .equal, toItem: titleView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint.init(item: self.titleLabel, attribute: .trailing, relatedBy: .equal, toItem: titleView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true self.progressView = ProgressView.init(frame: CGRect.init(x: 0, y: 0, width: 18, height: 18), style: .circleProgressView) self.progressView?.translatesAutoresizingMaskIntoConstraints = false self.progressView?.isHidden = true if let loadingEventListView = self.progressView { titleView.addSubview(loadingEventListView) NSLayoutConstraint.init(item: loadingEventListView, attribute: .centerY, relatedBy: .equal, toItem: titleView, attribute: .centerY, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint.init(item: loadingEventListView, attribute: .trailing, relatedBy: .equal, toItem: self.titleLabel, attribute: .leading, multiplier: 1.0, constant: -11).isActive = true NSLayoutConstraint.init(item: loadingEventListView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 18).isActive = true NSLayoutConstraint.init(item: loadingEventListView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1.0, constant: 18).isActive = true } self.navigationItem.titleView = titleView } } else { addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) moreSiteButton.setImage(TPImageLiteral("media_multi_style_more"), for: .normal) moreSiteButton.addTarget(self, action: #selector(deviceListMoreButtonClickForPerson), for: .touchUpInside) moreSiteButton.backgroundColor = .clear } } else { // navigationItem.leftBarButtonItem = nil tabCollectionHeightConstant.constant = 30 if showLocalDeviceOnly { tabCollectionHeightConstant.constant = 52 tabNames.removeAll() tabNames.append(LocalizedString(key: deviceListSubTitleDeviceList)) addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) } selectedTabTypeForPersonal = UserDefaults.standard.deviceListSelectedTypeForPersonal ?? .all if selectedTabTypeForPersonal == .favorite { selectedTabIndex = collectDviceTabIndexForPersonal } else { selectedTabIndex = allDviceTabIndexForPersonal } moreSiteButton.setImage(TPImageLiteral("common_light_more_nor"), for: .normal) moreSiteButton.addTarget(self, action: #selector(deviceListMoreButtonClickForPerson), for: .touchUpInside) moreSiteButton.setEnlargeEdgeWithTop(10.0, left: 20.0, bottom: 20.0, right: 20.0) moreSiteButton.backgroundColor = .clear } if showLocalDeviceOnly { moreSiteButton.isHidden = localDeviceCount == 0 } else { moreSiteButton.isHidden = !appContext.isLogin } localDeviceView.isHidden = true localDeviceView.layer.masksToBounds = true localDeviceView.layer.cornerRadius = 8 localDeviceTitleLabel.text = LocalizedString(key: mineItems_LocalDevice_title) // TODO: 替换文案 localDeviceCountLabel.text = String(format: LocalizedString(key: deviceListNumberOfDevices), localDeviceCount) localDeviceView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(gotoLocalDeviceVC(_:)))) LocalDeviceViewHeight.constant = CGFloat(0) localDeviceView.isHidden = true if self.showLocalDeviceOnly { navigationItem.title = LocalizedString(key: mineItems_LocalDevice_title) } tabBarContainer.backgroundColor = .clear tabBarContainer.addSubview(self.multiLiveBtn) if self.showLocalDeviceOnly { self.view.addSubview(self.topTipsView) //3.设置约束 topTipsView.snp.makeConstraints({ make in make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top) make.leading.equalToSuperview().offset(8) make.trailing.equalToSuperview().offset(-8) }) let userDefaults = UserDefaults.standard self.showTopTips = userDefaults.integer(forKey: TPVIGILOCALVCTOPTIPSSHOW) != -1 } self.multiLiveBtn.snp.remakeConstraints { make in make.centerY.equalTo(self.moreSiteButton) make.width.height.equalTo(24) make.trailing.equalTo(self.moreSiteButton.snp.leading).offset(-14) } setupNetworkMonitor() if !showLocalDeviceOnly { setupPageContainerViews() } }
11-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值