Próbuję dowiedzieć się, jak używać różnych stanów UISegmentedControl do przełączania widoków, podobnie jak Apple robi to w App Store podczas przełączania między „Najlepiej płatne” i „Najlepsze bezpłatne”.
Próbuję dowiedzieć się, jak używać różnych stanów UISegmentedControl do przełączania widoków, podobnie jak Apple robi to w App Store podczas przełączania między „Najlepiej płatne” i „Najlepsze bezpłatne”.
Odpowiedzi:
Najprostszym podejściem jest posiadanie dwóch widoków, w których można przełączać ich widoczność, aby wskazać, który widok został wybrany. Oto przykładowy kod pokazujący, jak można to zrobić, zdecydowanie nie jest to zoptymalizowany sposób obsługi widoków, ale tylko po to, aby zademonstrować, jak można użyć UISegmentControl do przełączania widocznego widoku:
- (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];
}
}
Możesz oczywiście jeszcze bardziej zmienić współczynnik w kodzie, aby ukryć / pokazać właściwy widok.
W moim przypadku moje widoki są dość złożone i nie mogę po prostu zmienić ukrytej właściwości różnych widoków, ponieważ zajmowałoby to zbyt dużo pamięci.
Wypróbowałem kilka rozwiązań i żadne z nich nie działało dla mnie ani nie działało błędnie, szczególnie z titleView paska navBar nie zawsze pokazującym segmentedControl podczas wypychania / wyskakiwania widoków.
Znalazłem ten wpis na blogu dotyczący problemu, który wyjaśnia, jak to zrobić we właściwy sposób. Wygląda na to, że podczas WWDC'2010 skorzystał z pomocy inżynierów Apple, aby opracować to rozwiązanie.
http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited
Rozwiązanie w tym linku to bez wątpienia najlepsze rozwiązanie problemu, jakie znalazłem do tej pory. Przy niewielkiej regulacji działał również dobrze z tabBarem na dole
Lub jeśli jest to tabela, możesz ponownie załadować tabelę i w cellForRowAtIndex wypełnić tabelę z różnych źródeł danych na podstawie wybranej opcji segmentu.
Jeden z pomysłów polega na tym, aby widok z segmentowanymi kontrolkami miał widok kontenera, który można wypełnić różnymi widokami podrzędnymi (dodać jako jedyny widok podrzędny widoku kontenera, gdy segmenty są przełączane). Możesz nawet mieć osobne kontrolery widoku dla tych widoków podrzędnych, chociaż musisz przekazywać ważne metody, takie jak „viewWillAppear” i „viewWillDisappear”, jeśli ich potrzebujesz (i będą musieli powiedzieć, pod jakim kontrolerem nawigacyjnym się znajdują).
Generalnie działa to całkiem nieźle, ponieważ możesz rozłożyć widok główny za pomocą kontenera w IB, a podglądy wypełnią dowolną przestrzeń, na jaką pozwala im kontener (upewnij się, że maski autoresize są poprawnie skonfigurowane).
Spróbuj użyć SNFSegmentedViewController
komponentu open source, który robi dokładnie to, czego szukasz, w takiej konfiguracji UITabBarController
.
Z odpowiedzi @Ronnie Liew tworzę to:
//
// 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
Przypisz .H w
UISegmentedControl *lblSegChange;
- (IBAction)segValChange:(UISegmentedControl *) sender
Zadeklaruj .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];
}
}
Wersja Swift:
Nadrzędny kontroler widoku jest odpowiedzialny za ustawienie rozmiaru i położenia widoku każdego podrzędnego kontrolera widoku. Widok podrzędnego kontrolera widoku staje się częścią hierarchii widoków nadrzędnego kontrolera widoku.
Zdefiniuj leniwe właściwości:
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
}()
Pokaż / ukryj kontrolery widoku potomnego:
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()
}
Zarządzaj SegmentedControl tapEvent
private func updateView() {
if segmentedControl.selectedSegmentIndex == 0 {
remove(asChildViewController: sessionsViewController)
add(asChildViewController: summaryViewController)
} else {
remove(asChildViewController: summaryViewController)
add(asChildViewController: sessionsViewController)
}
}
Oczywiście możesz używać w swoich podrzędnych klasach kontrolerów widoku:
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")
}
Źródła: https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/
Szybka wersja Swift:
@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) {
if segmentControl.selectedSegmentIndex == 0 {
// do something
} else {
// do something else
}
}