ios 如何使用 UISegmentedControl 切换视图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1047114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:04:37  来源:igfitidea点击:

How do I use a UISegmentedControl to switch views?

iosobjective-ciphoneuisegmentedcontrol

提问by Mark Adams

I'm trying to figure out how to use the different states of a UISegmentedControl to switch views, similar to how Apple does it in the App Store when switiching between 'Top Paid' and 'Top Free'.

我试图弄清楚如何使用 UISegmentedControl 的不同状态来切换视图,类似于 Apple 在 App Store 中在“Top Paid”和“Top Free”之间切换时的做法。

回答by Ronnie Liew

The simplest approach is to have two views that you can toggle their visibility to indicate which view has been selected. Here is some sample code on how it can be done, definitely not an optimized way to handle the views but just to demonstrate how you can use the UISegmentControlto toggle the visible view:

最简单的方法是拥有两个视图,您可以切换它们的可见性以指示已选择哪个视图。下面是一些关于如何完成的示例代码,绝对不是处理视图的优化方法,只是为了演示如何使用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];
  }
}


You can of course further re-factor the code to hide/show the right view.


您当然可以进一步重构代码以隐藏/显示正确的视图。

回答by Marc M

In my case my views are quite complex and I cannot just change the hidden property of different views because it would take up too much memory.

就我而言,我的视图非常复杂,我不能只更改不同视图的隐藏属性,因为它会占用太多内存。

I've tried several solutions and non of them worked for me, or performed erratically, specially with the titleView of the navBar not always showing the segmentedControl when pushing/popping views.

我已经尝试了几种解决方案,但没有一个对我有用,或者表现不稳定,特别是导航栏的 titleView 在推送/弹出视图时并不总是显示 segmentedControl。

I found this blog post about the issue that explains how to do it in the proper way. Seems he had the aid of Apple engineers at WWDC'2010 to come up with this solution.

我发现这篇关于这个问题的博客文章解释了如何以正确的方式做到这一点。似乎他在 WWDC'2010 的 Apple 工程师的帮助下提出了这个解决方案。

http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited

http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited

The solution in this link is hands down the best solution I've found about the issue so far. With a little bit of adjustment it also worked fine with a tabBar at the bottom

此链接中的解决方案是迄今为止我发现的有关该问题的最佳解决方案。稍加调整,底部的 tabBar 也能正常工作

回答by lostInTransit

Or if its a table, you can reload the table and in cellForRowAtIndex, populate the table from different data sources based on the segment option selected.

或者,如果它是一个表,您可以重新加载该表并在 cellForRowAtIndex 中,根据所选的段选项从不同的数据源填充该表。

回答by Kendall Helmstetter Gelner

One idea is to have the view with the segmented controls have a container view that you fill with the different subviews (add as a sole subview of the container view when the segments are toggled). You can even have separate view controllers for those subviews, though you have to forward on important methods like "viewWillAppear" and "viewWillDisappear" if you need them (and they will have to be told what navigation controller they are under).

一种想法是让带有分段控件的视图具有一个容器视图,您可以使用不同的子视图填充该视图(在切换段时添加为容器视图的唯一子视图)。您甚至可以为这些子视图使用单独的视图控制器,但如果您需要它们,您必须转发诸如“viewWillAppear”和“viewWillDisappear”之类的重要方法(并且必须告诉他们它们所在的导航控制器)。

Generally that works pretty well because you can lay out the main view with container in IB, and the subviews will fill whatever space the container lets them have (make sure your autoresize masks are set up properly).

通常效果很好,因为您可以在 IB 中布置带有容器的主视图,并且子视图将填充容器允许它们拥有的任何空间(确保正确设置了自动调整大小的掩码)。

回答by sethfri

Try using SNFSegmentedViewController, an open-source component that does exactly what you're looking for with a setup like UITabBarController.

尝试使用SNFSegmentedViewController,这是一个开源组件,它可以通过类似UITabBarController.

回答by Anbu.Karthik

Assign .H in

分配 .H

 UISegmentedControl *lblSegChange;

- (IBAction)segValChange:(UISegmentedControl *) sender

Declare .M

声明.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];
 }
} 

回答by Envil

From the answer of @Ronnie Liew, I create this:

根据@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

回答by SlavisaPetkovic

Swift version:

迅捷版:

The parent view controller is responsible for setting the size and position of the view of each child view controller. The view of the child view controller becomes part of the parent view controller's view hierarchy.

父视图控制器负责设置每个子视图控制器的视图的大小和位置。子视图控制器的视图成为父视图控制器视图层次结构的一部分。

Define lazy properties:

定义惰性属性:

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
}()

Show/Hide Child View Controllers:

显示/隐藏子视图控制器:

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()
}

Manage SegmentedControl tapEvent

管理 SegmentedControl tapEvent

private func updateView() {
    if segmentedControl.selectedSegmentIndex == 0 {
        remove(asChildViewController: sessionsViewController)
        add(asChildViewController: summaryViewController)
    } else {
        remove(asChildViewController: summaryViewController)
        add(asChildViewController: sessionsViewController)
    }
}

And of course you are able to use within your child view controller classes:

当然,您可以在子视图控制器类中使用:

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")
}

Reference: https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/

参考:https: //cocoacasts.com/managing-view-controllers-with-container-view-controllers/

回答by Bright Future

A quick Swift Version:

一个快速的 Swift 版本:

@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) {

    if segmentControl.selectedSegmentIndex == 0 {

        // do something
    } else {

        // do something else
    }
}