Я пытаюсь понять, как использовать различные состояния UISegmentedControl для переключения представлений, аналогично тому, как Apple делает это в App Store при переключении между «Top Paid» и «Top Free».
Я пытаюсь понять, как использовать различные состояния UISegmentedControl для переключения представлений, аналогично тому, как Apple делает это в App Store при переключении между «Top Paid» и «Top Free».
Ответы:
Самый простой подход - иметь два представления, видимость которых можно переключать, чтобы указать, какой вид был выбран. Вот пример кода того, как это можно сделать, определенно не оптимизированный способ обработки представлений, а просто демонстрация того, как вы можете использовать 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];
}
}
Вы, конечно, можете дополнительно изменить коэффициент кода, чтобы скрыть / показать правильное представление.
В моем случае мои представления довольно сложны, и я не могу просто изменить скрытое свойство разных представлений, потому что это займет слишком много памяти.
Я пробовал несколько решений, и ни одно из них не сработало для меня или работало беспорядочно, особенно с titleView в navBar, не всегда отображающим segmentedControl при нажатии / открытии представлений.
Я нашел это сообщение в блоге о проблеме, в котором объясняется, как это сделать правильно. Кажется, ему помогли инженеры Apple на WWDC'2010, чтобы придумать это решение.
http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited
Решение по этой ссылке - лучшее решение, которое я нашел до сих пор. С небольшой настройкой он также отлично работал с tabBar внизу
Или, если это таблица, вы можете перезагрузить таблицу и в cellForRowAtIndex заполнить таблицу из разных источников данных в зависимости от выбранного параметра сегмента.
Одна из идей состоит в том, чтобы представление с сегментированными элементами управления имело представление контейнера, которое вы заполняете различными подпредставлениями (добавляйте как единственное подпредставление представления контейнера при переключении сегментов). У вас даже могут быть отдельные контроллеры представления для этих подпредставлений, хотя вы должны пересылать важные методы, такие как «viewWillAppear» и «viewWillDisappear», если они вам нужны (и им нужно будет сообщить, под каким контроллером навигации они находятся).
Как правило, это работает очень хорошо, потому что вы можете выложить основное представление с контейнером в IB, а вложенные представления будут заполнять все пространство, которое контейнер позволяет им (убедитесь, что ваши маски автоматического изменения размера настроены правильно).
Попробуйте использовать SNFSegmentedViewController
компонент с открытым исходным кодом, который делает именно то, что вы ищете, с подобной настройкой UITabBarController
.
Из ответа @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
Назначьте .H в
UISegmentedControl *lblSegChange;
- (IBAction)segValChange:(UISegmentedControl *) sender
Объявить .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];
}
}
Быстрая версия:
Контроллер родительского представления отвечает за установку размера и положения представления каждого контроллера дочернего представления. Представление дочернего контроллера представления становится частью иерархии представлений родительского контроллера представления.
Определите ленивые свойства:
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
}()
Показать / скрыть дочерние контроллеры представления:
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()
}
Управление SegmentedControl tapEvent
private func updateView() {
if segmentedControl.selectedSegmentIndex == 0 {
remove(asChildViewController: sessionsViewController)
add(asChildViewController: summaryViewController)
} else {
remove(asChildViewController: summaryViewController)
add(asChildViewController: sessionsViewController)
}
}
И, конечно же, вы можете использовать в своих дочерних классах контроллера представления:
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")
}
Ссылка: https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/
Быстрая версия Swift:
@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) {
if segmentControl.selectedSegmentIndex == 0 {
// do something
} else {
// do something else
}
}