這個問題讓我瘋狂。當用戶更改分段控件的選定「選項卡」時,我試圖更改viewController
。我花了幾個小時的時間進行研究,一直未能找到可以通過故事板完成的答案。分段控制改變時更改視圖控制器
它真的很麻煩,因爲設置選項卡應用程序非常簡單,但試圖使用像Tab應用程序一樣的分段控件只是不起作用。我已經知道如何檢測在分段控制中選擇哪個索引。我怎樣才能做到這一點?
非常感謝。
這個問題讓我瘋狂。當用戶更改分段控件的選定「選項卡」時,我試圖更改viewController
。我花了幾個小時的時間進行研究,一直未能找到可以通過故事板完成的答案。分段控制改變時更改視圖控制器
它真的很麻煩,因爲設置選項卡應用程序非常簡單,但試圖使用像Tab應用程序一樣的分段控件只是不起作用。我已經知道如何檢測在分段控制中選擇哪個索引。我怎樣才能做到這一點?
非常感謝。
我會說這是多少卡如果要在UIViewController
內更改子視圖,則可以在故事板中設置子視圖,並在控制器中將它們與IBOulets
掛鉤,您可以將視圖的hidden
屬性設置爲YES或NO,具體取決於所單擊的控件。
現在,如果您使用@Robotic Cat的方法,這也是一個很好的解決方案,您可以在應用程序的工作方式上有更多的模塊化,考慮到您必須使用我提供的解決方案將所有邏輯放在一個控制器中。
我喜歡你的建議只是在Xcode上試用過,看起來不錯並且易於實現。我唯一擔心的是將背景隱藏在背景中效率低下嗎? – 2012-07-10 23:02:10
我還沒有讀過te開發人員文檔中任何與此相反的內容,儘管您必須考慮如果添加了大量視覺元素,它會佔用內存,因此明智地做。爲了避免這種情況,您可以動態地灌輸所需的一切,儘管我相信已經設置好所有元素的開銷很小。例如,我只有4個子視圖,每個子視圖都有1或2個文本框。 – 8vius 2012-07-10 23:47:49
在我的一個iPad應用程序中,我有一個視圖控制器,它有7個子視圖可以顯示或隱藏,每個子視圖都有自己的一組控件。總共有大約60個視圖和子視圖(標籤,按鈕等)。我沒有注意到任何緩慢或猶豫,並且Profier不會在內存或CPU中發現任何巨大的峯值。顯然,你應該徹底測試你自己的解決方案,但我懷疑你會遇到問題。 – 2012-07-11 00:04:23
UISegmentedControl有點不同,它沒有委託協議,你必須使用「添加目標」樣式。在你的情況下,你想要做的是添加一個目標,當UISegmentedControl改變時(這可能是父視圖控制器),然後該目標可以處理標籤切換。
例如:
[self.mainSegmentedControl addTarget:self action:@selector(changedSegmentedControl:) forControlEvents:UIControlEventValueChanged];
在這個例子中,代碼被從一些視圖/控制器可以訪問的變量的分段控制調用。我們添加自己以獲取changedSegmentedControl:方法。
那麼你就必須像這樣一種方法:
- (void)changedSegmentedControl:(id)sender
{
UISegmentedControl *ctl = sender;
NSLog(@"Changed value of segmented control to %d", ctl.selectedSegmentIndex);
// Code to change View Controller goes here
}
注:這是從內存中寫入未經測試的代碼 - 請相應參考文檔。
注:答案與iOS視圖控制器遏制碼5+包括@接口部分
更新在我的應用程序,我有在導航欄段控制,並單擊視圖控制器「標籤」切換視圖控制器。基本思想是有一個視圖控制器的數組,並使用段索引切換它們(以及indexDidChangeForSegmentedControl IBAction)。
我的應用程序的示例代碼(iOS 5或更高版本)(這是用於2個視圖控制器的,但它很平凡。擴展到多個視圖控制器);代碼是稍微比爲iOS 4長,但是將保持對象圖完好同時,它採用ARC:
@interface MyViewController()
// Segmented control to switch view controllers
@property (weak, nonatomic) IBOutlet UISegmentedControl *switchViewControllers;
// Array of view controllers to switch between
@property (nonatomic, copy) NSArray *allViewControllers;
// Currently selected view controller
@property (nonatomic, strong) UIViewController *currentViewController;
@end
@implementation UpdateScoreViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// Create the score view controller
ViewControllerA *vcA = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerA"];
// Create the penalty view controller
ViewControllerB *vcB = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"];
// Add A and B view controllers to the array
self.allViewControllers = [[NSArray alloc] initWithObjects:vcA, vcB, nil];
// Ensure a view controller is loaded
self.switchViewControllers.selectedSegmentIndex = 0;
[self cycleFromViewController:self.currentViewController toViewController:[self.allViewControllers objectAtIndex:self.switchViewControllers.selectedSegmentIndex]];
}
#pragma mark - View controller switching and saving
- (void)cycleFromViewController:(UIViewController*)oldVC toViewController:(UIViewController*)newVC {
// Do nothing if we are attempting to swap to the same view controller
if (newVC == oldVC) return;
// Check the newVC is non-nil otherwise expect a crash: NSInvalidArgumentException
if (newVC) {
// Set the new view controller frame (in this case to be the size of the available screen bounds)
// Calulate any other frame animations here (e.g. for the oldVC)
newVC.view.frame = CGRectMake(CGRectGetMinX(self.view.bounds), CGRectGetMinY(self.view.bounds), CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds));
// Check the oldVC is non-nil otherwise expect a crash: NSInvalidArgumentException
if (oldVC) {
// Start both the view controller transitions
[oldVC willMoveToParentViewController:nil];
[self addChildViewController:newVC];
// Swap the view controllers
// No frame animations in this code but these would go in the animations block
[self transitionFromViewController:oldVC
toViewController:newVC
duration:0.25
options:UIViewAnimationOptionLayoutSubviews
animations:^{}
completion:^(BOOL finished) {
// Finish both the view controller transitions
[oldVC removeFromParentViewController];
[newVC didMoveToParentViewController:self];
// Store a reference to the current controller
self.currentViewController = newVC;
}];
} else {
// Otherwise we are adding a view controller for the first time
// Start the view controller transition
[self addChildViewController:newVC];
// Add the new view controller view to the ciew hierarchy
[self.view addSubview:newVC.view];
// End the view controller transition
[newVC didMoveToParentViewController:self];
// Store a reference to the current controller
self.currentViewController = newVC;
}
}
}
- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender {
NSUInteger index = sender.selectedSegmentIndex;
if (UISegmentedControlNoSegment != index) {
UIViewController *incomingViewController = [self.allViewControllers objectAtIndex:index];
[self cycleFromViewController:self.currentViewController toViewController:incomingViewController];
}
}
@end
原始實例(iOS 4的或前):
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// Create the score view controller
AddHandScoreViewController *score = [self.storyboard instantiateViewControllerWithIdentifier:@"AddHandScore"];
// Create the penalty view controller
AddHandPenaltyViewController *penalty = [self.storyboard instantiateViewControllerWithIdentifier:@"AddHandPenalty"];
// Add Score and Penalty view controllers to the array
self.allViewControllers = [[NSArray alloc] initWithObjects:score, penalty, nil];
// Ensure the Score controller is loaded
self.switchViewControllers.selectedSegmentIndex = 0;
[self switchToController:[self.allViewControllers objectAtIndex:self.switchViewControllers.selectedSegmentIndex]];
}
#pragma mark - View controller switching and saving
- (void)switchToController:(UIViewController *)newVC
{
if (newVC) {
// Do nothing if we are in the same controller
if (newVC == self.currentViewController) return;
// Remove the current controller if we are loaded and shown
if([self.currentViewController isViewLoaded]) [self.currentViewController.view removeFromSuperview];
// Resize the new view controller
newVC.view.frame = CGRectMake(CGRectGetMinX(self.view.bounds), CGRectGetMinY(self.view.bounds), CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds));
// Add the new controller
[self.view addSubview:newVC.view];
// Store a reference to the current controller
self.currentViewController = newVC;
}
}
- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender {
NSUInteger index = sender.selectedSegmentIndex;
if (UISegmentedControlNoSegment != index) {
UIViewController *incomingViewController = [self.allViewControllers objectAtIndex:index];
[self switchToController:incomingViewController];
}
}
真的很好的解決方案。感謝分享這個。 – Mike 2013-03-13 06:23:35
@Robotic Cat:我有點困惑,爲什麼你將子視圖控制器的框架設置爲與父視圖控制器相同。這個父視圖控制器不包含UISegmentedControl嗎?如果是這樣,孩子視圖控制器不會掩蓋它嗎? – Marplesoft 2013-08-10 22:32:06
@Marplesoft:通常「UISegmentedControl」位於導航欄中。顯然,如果你的'UISegmentedControl'在你的視圖控制器中,你應該將你的自動佈局約束或框架設置爲你的應用的正確值。 – 2013-08-10 23:39:08
查看此窗格:https://github.com/xmartlabs/XLMailBoxContainer。它使視圖控制器之間的UI動畫。這些視圖控制器可以擴展UITableViewController或任何其他視圖控制器。
我希望這對你有所幫助!
您是否想換出_view_或_view controller_?他們是兩回事。如果是後者,我建議將所有東西都放到一個視圖控制器中,並根據需要顯示或隱藏子視圖。 – 2012-07-10 22:29:36
嗯,我真的是iOS新手,我想到的最簡單的事情就是改變viewController就像選項卡式應用程序一樣。您是否建議製作各種視圖並使用相同的視圖控制器來管理它們?如果是這樣,我該怎麼做?非常感謝 – 2012-07-10 22:33:56