UISegmentedControl Best Practice

后端 未结 3 1548
醉酒成梦
醉酒成梦 2020-12-04 11:25

I\'m trying to work out the \"best\" way to use a UISegmentedControl for an iPhone application. I\'ve read a few posts here on stackoverflow and seen a few peo

3条回答
  •  情书的邮戳
    2020-12-04 12:17

    I've come across this requirement as well in an iPad application.

    The solution I came to was to create specialized view controllers for each style of view to handle business logic relating to those views (ie. relating to each segment), and programatically add/remove them as subviews to a 'managing' controller in response to selected segment index changes.

    To do this, one has to create an additional UIViewController subclass that manages UISegmentedControl changes, and adds/removes the subviews.

    The code below does all this, also taking care of a few caveats/extras:

    • viewWillAppear/viewWillDisappear/etc, aren't called on the subviews automatically, and need to be told via the 'managing' controller
    • viewWillAppear/viewWillDisappear/etc, aren't called on 'managing' controller when it's within a navigation controller, hence the navigation controller delegate
    • If you'd like to push onto a navigation stack from within a segment's subview, you need to call back on to the 'managing' view to do it, since the subview has been created outside of the navigation hierarchy, and won't have a reference to the navigation controller.
    • If used within a navigation controller scenario, the back button is automatically set to the name of the segment.

    Interface:

    @interface SegmentManagingViewController : UIViewController  {
        UISegmentedControl    * segmentedControl;
        UIViewController      * activeViewController;
        NSArray               * segmentedViewControllers;
    }
    
    @property (nonatomic, retain) IBOutlet UISegmentedControl * segmentedControl;
    @property (nonatomic, retain) UIViewController            * activeViewController;
    @property (nonatomic, retain) NSArray                     * segmentedViewControllers;
    
    @end
    

    Implementation:

    @interface SegmentManagingViewController ()
    - (void)didChangeSegmentControl:(UISegmentedControl *)control;
    @end
    
    @implementation SegmentManagingViewController
    
    @synthesize segmentedControl, activeViewController, segmentedViewControllers;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIViewController * controller1 = [[MyViewController1 alloc] initWithParentViewController:self];
        UIViewController * controller2 = [[MyViewController2 alloc] initWithParentViewController:self];
        UIViewController * controller3 = [[MyViewController3 alloc] initWithParentViewController:self];
    
        self.segmentedViewControllers = [NSArray arrayWithObjects:controller1, controller2, controller3, nil];
        [controller1 release];
        [controller2 release];
        [controller3 release];
    
        self.navigationItem.titleView = self.segmentedControl =
        [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"Seg 1", @"Seg 2", @"Seg 3", nil]];
        self.segmentedControl.selectedSegmentIndex = 0;
        self.segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
    
        [self.segmentedControl addTarget:self action:@selector(didChangeSegmentControl:) forControlEvents:UIControlEventValueChanged];
    
        [self didChangeSegmentControl:self.segmentedControl]; // kick everything off
    }
    
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        [self.activeViewController viewWillAppear:animated];
    }
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        [self.activeViewController viewDidAppear:animated];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [self.activeViewController viewWillDisappear:animated];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
        [self.activeViewController viewDidDisappear:animated];
    }
    
    #pragma mark -
    #pragma mark UINavigationControllerDelegate control
    
    // Required to ensure we call viewDidAppear/viewWillAppear on ourselves (and the active view controller)
    // inside of a navigation stack, since viewDidAppear/willAppear insn't invoked automatically. Without this
    // selected table views don't know when to de-highlight the selected row.
    
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        [viewController viewDidAppear:animated];
    }
    
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        [viewController viewWillAppear:animated];
    }
    
    #pragma mark -
    #pragma mark Segment control
    
    - (void)didChangeSegmentControl:(UISegmentedControl *)control {
        if (self.activeViewController) {
            [self.activeViewController viewWillDisappear:NO];
            [self.activeViewController.view removeFromSuperview];
            [self.activeViewController viewDidDisappear:NO];
        }
    
        self.activeViewController = [self.segmentedViewControllers objectAtIndex:control.selectedSegmentIndex];
    
        [self.activeViewController viewWillAppear:NO];
        [self.view addSubview:self.activeViewController.view];
        [self.activeViewController viewDidAppear:NO];
    
        NSString * segmentTitle = [control titleForSegmentAtIndex:control.selectedSegmentIndex];
        self.navigationItem.backBarButtonItem  = [[UIBarButtonItem alloc] initWithTitle:segmentTitle style:UIBarButtonItemStylePlain target:nil action:nil];
    }
    
    #pragma mark -
    #pragma mark Memory management
    
    - (void)dealloc {
        self.segmentedControl = nil;
        self.segmentedViewControllers = nil;
        self.activeViewController = nil;
        [super dealloc];
    }
    
    @end
    

    Hope this helps.

提交回复
热议问题