Вопрос по objective-c, ios, iphone – Как использовать UISegmentedControl для переключения представлений?

80

Я пытаюсь выяснить, как использовать различные состояния UISegmentedControl для переключения представлений, подобно тому, как это делает Apple в App Store при переключении между «Top Paid». и "Top Free".

Ваш Ответ

10   ответов
17

если это таблица, вы можете перезагрузить таблицу и в cellForRowAtIndex заполнить таблицу из разных источников данных на основе выбранного параметра сегмента.

111

чтобы иметь два вида, которые можно переключать их видимость, чтобы указать, какой вид был выбран. Вот пример кода о том, как это можно сделать, определенно не оптимизированный способ обработки представлений, а просто демонстрация того, как вы можете использовать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];
  }
}


Конечно, вы можете еще раз изменить код, чтобы скрыть / показать правильный вид.

использование представлений контейнера может привести к проблемам с панелью навигации. особенно когда вы используете полупрозрачный. из моего опыта это не рекомендуемое решение
«определенно не оптимизированный способ обработки представлений»; - Зачем?
@AdamWaite, потому что все представления должны постоянно храниться в памяти. Если ваши представления слишком сложны и / или содержат много других элементов, это повлияет на общую производительность. Этот кусок кода также может быть реорганизован.
@Stas Вы правы, лучше разделить логику между несколькими контроллерами представления, каждый из которых отвечает за свои действия и поведение
2

 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];
 }
} 
1

A quick Swift Version:

@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) {

    if segmentControl.
        // do something
    } else {

        // do something else
    }
}
2

//
//  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
2

Родительский контроллер представления отвечает за установку размера и положения представления каждого дочернего контроллера представления. Представление дочернего контроллера представления становится частью иерархии представлений родительского контроллера представления.

Определите ленивые свойства:

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()
}

Управление сегментированным управлением 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/

@BasilePerrenoud Только что обновил ответ с важной и наиболее важной частью решения.
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. -From Review
45

и я не могу просто изменить скрытое свойство различных представлений, потому что это заняло бы слишком много памяти.

Я пробовал несколько решений, и ни одно из них не работало для меня или не работало хаотично, особенно с titleView панели navBar, не всегда показывающей segmentedControl при нажатии / выталкивании представлений.

Я нашел этот пост в блоге о проблеме, которая объясняет, как это сделать правильно. Похоже, что он помог инженерам Apple на WWDC'2010, чтобы придумать это решение.

http://redartisan.com/2010/6/27/uisegmented-control-view-switching-revisited

Решение, приведенное в этой ссылке, представляет собой лучшее решение, которое я до сих пор нашел по этой проблеме. С небольшой настройкой он также работал нормально с вкладкой внизу

Да, это кажется отличным решением, но как мне настроить его для работы с tabBarController с уже установленными навигационными контроллерами?
К счастью,Implementing a Container View Controller работал без нареканий! Даже сегы работают как положено.
Есть ли способ иметь горизонтальную анимацию пролистывания между представлениями. Или это работает только без анимации?
Я попытался заставить это работать должным образом с панелью инструментов внизу без успеха,stackoverflow.com/questions/4748120/… Можете ли вы помочь мне?
Спасибо за отличную находку. Определенно хорошее и элегантное решение для этой методологии.
7

чтобы у представления с сегментированными элементами управления было представление контейнера, которое вы заполняете различными подпредставлениями (добавляйте как отдельное подпредставление представления контейнера, когда сегменты переключаются). Вы даже можете иметь отдельные контроллеры представлений для этих подпредставлений, хотя вам нужно перенаправить на такие важные методы, как & quot; viewWillAppear & quot; и & quot; viewWillDisappear & quot; если они вам нужны (и им нужно будет сказать, под каким контроллером навигации они находятся).

Как правило, это работает довольно хорошо, потому что вы можете расположить основной вид с контейнером в IB, и подвиды будут заполнять все пространство, которое им позволяет контейнер (убедитесь, что маски автоматического изменения размера установлены правильно).

3

SNFSegmentedViewControllerкомпонент с открытым исходным кодом, который делает именно то, что вы ищете с такой настройкой, какUITabBarController.

7

это поможет вам переключаться между различными представлениями при изменении сегментов сегмента управления

Открывайте разные виды при выборе разных сегментов UISegmentControl

это хорошее решение!

Похожие вопросы