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