Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS5中使用UISegmentedControl切换ViewController_Ios_Uiviewcontroller_Uikit_Uisegmentedcontrol - Fatal编程技术网

在iOS5中使用UISegmentedControl切换ViewController

在iOS5中使用UISegmentedControl切换ViewController,ios,uiviewcontroller,uikit,uisegmentedcontrol,Ios,Uiviewcontroller,Uikit,Uisegmentedcontrol,我正在尝试一些非常简单的事情,但不知怎么的,我无法让它工作。我所要做的就是使用UISegmentedControl在两个视图控制器之间切换,例如在应用商店应用程序的“高光”选项卡中可以看到它 我正在使用iOS5和故事板 以下是我的故事情节: 所以我有一个根视图控制器和两个UITableView,这两个是我想要切换的TableView 下面是实现文件的样子 #import "SegmentedLocationViewController.h" #import "PastEventsLocatio

我正在尝试一些非常简单的事情,但不知怎么的,我无法让它工作。我所要做的就是使用UISegmentedControl在两个视图控制器之间切换,例如在应用商店应用程序的“高光”选项卡中可以看到它

我正在使用iOS5和故事板

以下是我的故事情节:

所以我有一个根视图控制器和两个UITableView,这两个是我想要切换的TableView

下面是实现文件的样子

#import "SegmentedLocationViewController.h"
#import "PastEventsLocationViewController.h"
#import "FutureEventsLocationViewController.h"

@interface SegmentedLocationViewController()
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedControl;
@property (strong, nonatomic) NSArray *viewControllers;
@end


@implementation SegmentedLocationViewController

@synthesize segmentedControl = _segmentedControl;
@synthesize viewControllers = _viewControllers;

- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl*)segmentedControl
{
    NSLog(@"index: %d", segmentedControl.selectedSegmentIndex);
}

- (void)setupViewControllers
{
    PastEventsLocationViewController *pastEventsLocationViewController = [[PastEventsLocationViewController alloc] initWithStyle:UITableViewStylePlain];
    FutureEventsLocationViewController *futureEventsLocationViewController = [[FutureEventsLocationViewController alloc] initWithStyle:UITableViewStylePlain];

    self.viewControllers = [NSArray arrayWithObjects:pastEventsLocationViewController, futureEventsLocationViewController, nil];
}

- (void)setupUI
{
    [self.segmentedControl addTarget:self action:@selector(indexDidChangeForSegmentedControl:) forControlEvents:UIControlEventValueChanged];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setupViewControllers];
    [self setupUI];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end
我可以触发开关事件并记录当前选择的索引。但我不知道接下来该怎么办


也许有人可以将我的注意力转向某个方向…?

您可以将初始视图控制器嵌入导航控制器中。通过选择故事板中的视图控制器,然后选择编辑器->嵌入->导航控制器来实现这一点

在indexDidChangeForSegmentedControl:方法中,只需将相应的视图控制器推送到导航堆栈:

- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl*)segmentedControl
{
    [self.navigationController pushViewController:[self.viewControllers objectAtIndex:[segmentedControl.selectedIndex]] animated:YES];

}
但是,当您使用故事板时,您的方法没有太多意义。
我不知道是否可以使用segues将单个分段控制按钮连接到视图控制器。试试看。

这段代码非常适合您,我将它用于我的一个新应用程序。
它使用了新的UIViewController包含API,允许UIViewController位于您自己的UIViewController中,而无需手动转发
ViewDidDisplay:

- (void)viewDidLoad {
    [super viewDidLoad];
    // add viewController so you can switch them later. 
    UIViewController *vc = [self viewControllerForSegmentIndex:self.typeSegmentedControl.selectedSegmentIndex];
    [self addChildViewController:vc];
    vc.view.frame = self.contentView.bounds;
    [self.contentView addSubview:vc.view];
    self.currentViewController = vc;
}
- (IBAction)segmentChanged:(UISegmentedControl *)sender {
    UIViewController *vc = [self viewControllerForSegmentIndex:sender.selectedSegmentIndex];
    [self addChildViewController:vc];
    [self transitionFromViewController:self.currentViewController toViewController:vc duration:0.5 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
        [self.currentViewController.view removeFromSuperview];
        vc.view.frame = self.contentView.bounds;
        [self.contentView addSubview:vc.view];
    } completion:^(BOOL finished) {
        [vc didMoveToParentViewController:self];
        [self.currentViewController removeFromParentViewController];
        self.currentViewController = vc;
    }];
    self.navigationItem.title = vc.title;
}

- (UIViewController *)viewControllerForSegmentIndex:(NSInteger)index {
    UIViewController *vc;
    switch (index) {
        case 0:
            vc = [self.storyboard instantiateViewControllerWithIdentifier:@"FooViewController"];
            break;
        case 1:
            vc = [self.storyboard instantiateViewControllerWithIdentifier:@"BarViewController"];
            break;
    }
    return vc;
}
我从Ray Wenderlich的书的第22章得到了这些东西。 不幸的是,我没有到教程的公共链接。但有一个名为“实现UIViewController控制”的WWDC 2011视频

编辑

self.typeSegmentedControl
是您的
UISegmentedControl

self.contentView
是容器视图的出口


self.currentViewController
只是我们用来存储当前使用的
UIViewController

的一个属性,这是Matthias Bauch解决方案,但无论如何都想在Swift中共享它! 编辑: 添加指向Swift 2.0现成演示应用程序的链接。


对于希望在swift中实现相同功能的人

import UIKit

class HomeController: UIViewController {

    var currentViewController:UIViewController?

    @IBOutlet weak var homeController: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let initialController:UIViewController = self.viewControllerForSegmentedIndex(0)

        self.addChildViewController(initialController)

        initialController.view.frame = self.homeController.bounds
        self.homeController.addSubview(initialController.view)
        self.currentViewController = initialController

    }

    @IBAction func segmentChanged(sender: UISegmentedControl) {

        let viewCOntroller:UIViewController = viewControllerForSegmentedIndex(sender.selectedSegmentIndex)

        self.addChildViewController(viewCOntroller)

        self.transitionFromViewController(self.currentViewController!, toViewController: viewCOntroller, duration: 0.5, options: UIViewAnimationOptions.TransitionFlipFromBottom, animations: {
            self.currentViewController?.view.removeFromSuperview()
            viewCOntroller.view.frame = self.homeController.bounds
            self.homeController.addSubview(viewCOntroller.view)

            }, completion:{ finished in

                viewCOntroller.didMoveToParentViewController(self)
                self.currentViewController?.removeFromParentViewController()
                self.currentViewController = viewCOntroller

        })

    }
    func viewControllerForSegmentedIndex(index:Int) -> UIViewController {
        var viewController:UIViewController?
        switch index {
        case 0:
            viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForFirstController")
            break
        case 1:
            viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForSecondController")
            break
        case 2:
            viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForThirdController")
            break
        default:
            break
        }
        return viewController!
    }
}
情节提要视图


A是根视图控制器,B、C是子视图控制器。 单击“段”时,添加子视图控制器

结果

设计

代码

import UIKit

class SegmentViewController: UIViewController {

    @IBOutlet weak var containerView: UIView!

    var leftViewController: LeftViewController!
    var rightViewController: RightViewController!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        if let sb = storyboard {
            leftViewController = sb.instantiateViewControllerWithIdentifier("leftViewController") as! LeftViewController

            switchViewController(from: nil, to: leftViewController)
        } else {
            print("storyboard is nil")
        }
    }

    func switchViewController(from fromVC: UIViewController?, to toVC: UIViewController?) {
        if let from = fromVC {
            from.willMoveToParentViewController(nil)
            from.view.removeFromSuperview()
            from.removeFromParentViewController()
        } else {
            print("fromVC is nil")
        }

        if let to = toVC {
            self.addChildViewController(to)
            to.view.frame = CGRectMake(0, 0, containerView.frame.width, containerView.frame.height)
            self.containerView.insertSubview(to.view, atIndex: 0)
            to.didMoveToParentViewController(self)
        } else {
            print("toVC is nil")
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.

        removeViewController()
    }

    func removeViewController() {
        if let leftVC = leftViewController {
            if let _ = leftVC.parentViewController {
                print("leftVC is using")
            } else {
                print("set leftVC = nil")
                leftViewController = nil
            }
        }

        if let rightVC = rightViewController {
            if let _ = rightVC.parentViewController {
                print("rightVC is using")
            } else {
                print("set rightVC = nil")
                rightViewController = nil
            }
        }
    }


    @IBAction func onSegmentValueChanged(sender: UISegmentedControl) {
        UIView.beginAnimations("xxx", context: nil)
        UIView.setAnimationDuration(0.4)
        UIView.setAnimationCurve(.EaseInOut)

        switch sender.selectedSegmentIndex {
        case 0:
            UIView.setAnimationTransition(.FlipFromRight, forView: self.containerView, cache: true)

            if let leftVC = leftViewController {
                switchViewController(from: rightViewController, to: leftVC)
            } else {
                if let sb = storyboard {
                    leftViewController = sb.instantiateViewControllerWithIdentifier("leftViewController") as! LeftViewController
                    switchViewController(from: rightViewController, to: leftViewController)
                } else {
                    print("storyboard is nil")
                }
            }
        default:
            UIView.setAnimationTransition(.FlipFromLeft, forView: self.containerView, cache: true)

            if let rightVC = rightViewController {
                switchViewController(from: leftViewController, to: rightVC)
            } else {
                if let sb = storyboard {
                    rightViewController = sb.instantiateViewControllerWithIdentifier("rightViewController") as! RightViewController
                    switchViewController(from: leftViewController, to: rightViewController)
                } else {
                    print("storyboard is nil")
                }
            }
        }

        UIView.commitAnimations()
    }
}

我最终使用了导航控制器来实现类似的功能

import UIKit

class BaseViewController: UIViewController {

  var currentSegmentIndex = 0

  @IBOutlet weak var segmentedControl: UISegmentedControl!

  override func viewDidLoad() {
    super.viewDidLoad()

    segmentedControl.selectedSegmentIndex = currentSegmentIndex
  }

  @IBAction func segmentedControlChanged(_ sender: Any) {
    let idx = segmentedControl.selectedSegmentIndex
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    switch idx {
    case 0:
      let vc = storyboard.instantiateViewController(
        withIdentifier: "Foo") as! FooViewController
      vc.currentSegmentIndex = 0
      navigationController?.viewControllers = [vc]
      break
    case 1:
      let vc = storyboard.instantiateViewController(
        withIdentifier: "Bar") as! BarViewController
      vc.currentSegmentIndex = 1
      navigationController?.viewControllers = [vc]
      break
    default:
      break
    }
  }
}

您是否考虑过用不同的值重新加载tableView?您是对的。我现在检查一下。我可能觉得太复杂了…我并没有用故事板来制作,但当我用nib文件来编写代码时,它就可以工作了。。。所以,谢谢你投我的票;)这个人很厉害。两个月后我才发现[自我故事板]。谢谢这似乎是一个愚蠢的问题,但当从头开始时,我会遇到诸如“ViewController*”类型的对象上找不到该属性“typeSegmentedControl”之类的问题。我可能在做一些愚蠢的事情,你不必为
typeSegmentedControl
(UISegmentedControl)添加
@属性我移动了
vc.view.frame=self.contentView.bounds在动画块之外,以避免子视图在转换期间超出contentView的边界,否则会导致闪烁。非常感谢!这让我高兴:)当然,这是我的荣幸:)
import UIKit

class BaseViewController: UIViewController {

  var currentSegmentIndex = 0

  @IBOutlet weak var segmentedControl: UISegmentedControl!

  override func viewDidLoad() {
    super.viewDidLoad()

    segmentedControl.selectedSegmentIndex = currentSegmentIndex
  }

  @IBAction func segmentedControlChanged(_ sender: Any) {
    let idx = segmentedControl.selectedSegmentIndex
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    switch idx {
    case 0:
      let vc = storyboard.instantiateViewController(
        withIdentifier: "Foo") as! FooViewController
      vc.currentSegmentIndex = 0
      navigationController?.viewControllers = [vc]
      break
    case 1:
      let vc = storyboard.instantiateViewController(
        withIdentifier: "Bar") as! BarViewController
      vc.currentSegmentIndex = 1
      navigationController?.viewControllers = [vc]
      break
    default:
      break
    }
  }
}