我正在尝试弄明白如何使用 UISegmentedControl 的不同状态来切换视图,类似于苹果在应用商店中在“最高付费”和“最高免费”之间切换时的做法。
最简单的方法是有两个视图,您可以切换它们的可见性,以指示选择了哪个视图。下面是一些关于如何实现的示例代码,绝对不是处理视图的优化方法,而只是演示如何使用 UISegmentControl切换可见视图:
- (IBAction)segmentSwitch:(id)sender { UISegmentedControl *segmentedControl = (UISegmentedControl *) sender; NSInteger selectedSegment = segmentedControl.selectedSegmentIndex; if (selectedSegment == 0) { //toggle the correct view to be visible [firstView setHidden:NO]; [secondView setHidden:YES]; } else{ //toggle the correct view to be visible [firstView setHidden:YES]; [secondView setHidden:NO]; } }
当然,您可以进一步重构代码以隐藏/显示正确的视图。
或者,如果它是一个表,则可以重新加载该表,并在 cellForRowAtIndex 中,根据所选的段选项从不同的数据源填充该表。
一种想法是让带分段控件的视图拥有一个容器视图,您可以用不同的子视图填充这个容器视图(当分段被切换时,作为容器视图的唯一子视图添加)。您甚至可以为这些子视图使用单独的视图控制器,但是如果您需要的话,您必须转发像“ viewWillAppear”和“ viewWillDisaper”这样的重要方法(并且必须告诉它们使用哪个导航控制器)。
一般来说,这样做效果很好,因为您可以在 IB 中用容器布局主视图,子视图将填充容器允许它们占用的任何空间(确保正确设置了自动调整大小的掩码)。
在我的情况下,我的视图是相当复杂的,我不能只是改变不同视图的隐藏属性,因为它会占用太多的内存。
我已经尝试了几种解决方案,但没有一种对我有效,或者执行得不稳定,特别是在导航栏的 titleView 在推送/弹出视图时并不总是显示 SegmentedControl。
我发现了这篇关于这个问题的博客文章,它解释了如何以正确的方式做到这一点。看起来他在2010年 WWDC 的苹果工程师的帮助下想出了这个解决方案。
Http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited
这个链接中的解决方案是我目前为止找到的最好的解决方案。稍微调整一下,在底部有一个标签栏也能正常工作
尝试使用 SNFSegmentedViewController,这是一个开放源码组件,通过像 UITabBarController这样的设置可以完成您正在寻找的工作。
SNFSegmentedViewController
UITabBarController
分配,进去
UISegmentedControl *lblSegChange; - (IBAction)segValChange:(UISegmentedControl *) sender
申报 M
- (IBAction)segValChange:(UISegmentedControl *) sender { if(sender.selectedSegmentIndex==0) { viewcontroller1 *View=[[viewcontroller alloc]init]; [self.navigationController pushViewController:view animated:YES]; } else { viewcontroller2 *View2=[[viewcontroller2 alloc]init]; [self.navigationController pushViewController:view2 animated:YES]; } }
根据“ Ronnie Liew”的回答,我创造了这个:
// // ViewController.m // ResearchSegmentedView // // Created by Ta Quoc Viet on 5/1/14. // Copyright (c) 2014 Ta Quoc Viet. All rights reserved. // #define SIZE_OF_SEGMENT 56 #import "ViewController.h" @interface ViewController () @end @implementation ViewController @synthesize theSegmentControl; UIView *firstView; UIView *secondView; CGRect leftRect; CGRect centerRect; CGRect rightRect; - (void)viewDidLoad { [super viewDidLoad]; leftRect = CGRectMake(-self.view.frame.size.width, SIZE_OF_SEGMENT, self.view.frame.size.width, self.view.frame.size.height-SIZE_OF_SEGMENT); centerRect = CGRectMake(0, SIZE_OF_SEGMENT, self.view.frame.size.width, self.view.frame.size.height-SIZE_OF_SEGMENT); rightRect = CGRectMake(self.view.frame.size.width, SIZE_OF_SEGMENT, self.view.frame.size.width, self.view.frame.size.height-SIZE_OF_SEGMENT); firstView = [[UIView alloc] initWithFrame:centerRect]; [firstView setBackgroundColor:[UIColor orangeColor]]; secondView = [[UIView alloc] initWithFrame:rightRect]; [secondView setBackgroundColor:[UIColor greenColor]]; [self.view addSubview:firstView]; [self.view addSubview:secondView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)segmentSwitch:(UISegmentedControl*)sender { NSInteger selectedSegment = sender.selectedSegmentIndex; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.2]; if (selectedSegment == 0) { //toggle the correct view to be visible firstView.frame = centerRect; secondView.frame = rightRect; } else{ //toggle the correct view to be visible firstView.frame = leftRect; secondView.frame = centerRect; } [UIView commitAnimations]; } @end
一个迅速的版本:
@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) { if segmentControl.selectedSegmentIndex == 0 { // do something } else { // do something else } }
快速版:
父视图控制器负责设置每个子视图控制器的视图的大小和位置。子视图控制器的视图成为父视图控制器视图层次结构的一部分。
定义惰性属性:
private lazy var summaryViewController: SummaryViewController = { // Load Storyboard let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) // Instantiate View Controller var viewController = storyboard.instantiateViewController(withIdentifier: "SummaryViewController") as! SummaryViewController // Add View Controller as Child View Controller self.add(asChildViewController: viewController) return viewController }() private lazy var sessionsViewController: SessionsViewController = { // Load Storyboard let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) // Instantiate View Controller var viewController = storyboard.instantiateViewController(withIdentifier: "SessionsViewController") as! SessionsViewController // Add View Controller as Child View Controller self.add(asChildViewController: viewController) return viewController }()
显示/隐藏子视图控制器:
private func add(asChildViewController viewController: UIViewController) { // Add Child View Controller addChildViewController(viewController) // Add Child View as Subview view.addSubview(viewController.view) // Configure Child View viewController.view.frame = view.bounds viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] // Notify Child View Controller viewController.didMove(toParentViewController: self) } private func remove(asChildViewController viewController: UIViewController) { // Notify Child View Controller viewController.willMove(toParentViewController: nil) // Remove Child View From Superview viewController.view.removeFromSuperview() // Notify Child View Controller viewController.removeFromParentViewController() }
管理分段控制录音事件
private func updateView() { if segmentedControl.selectedSegmentIndex == 0 { remove(asChildViewController: sessionsViewController) add(asChildViewController: summaryViewController) } else { remove(asChildViewController: summaryViewController) add(asChildViewController: sessionsViewController) } }
当然,您也可以在子视图控制器类中使用:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) print("Summary View Controller Will Appear") } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) print("Summary View Controller Will Disappear") }
参考文献: Https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/