Görünümler arasında geçiş yapmak için bir UISegmentedControl'ü nasıl kullanabilirim?


82

Görünümler arasında geçiş yapmak için bir UISegmentedControl'ün farklı durumlarının nasıl kullanılacağını anlamaya çalışıyorum, Apple'ın App Store'da 'En İyi Ücretli' ve 'En İyi Ücretsiz' arasında geçiş yaparken yaptığı gibi.

Yanıtlar:


113

En basit yaklaşım, hangi görünümün seçildiğini belirtmek için görünürlüğünü değiştirebileceğiniz iki görünüme sahip olmaktır. İşte bunun nasıl yapılabileceğine dair bazı örnek kodlar, kesinlikle görünümleri işlemek için optimize edilmiş bir yol değil, sadece UISegmentControl'ü görünür görünümü değiştirmek için nasıl kullanabileceğinizi göstermek için:

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


Elbette doğru görünümü gizlemek / göstermek için kodu daha fazla yeniden faktörleyebilirsiniz.


4
'kesinlikle görünümleri ele almak için optimize edilmiş bir yol değil' - neden?
Adam Waite

3
@AdamWaite çünkü tüm görünümler kalıcı olarak bellekte saklanmalıdır. Görüşleriniz çok karmaşıksa ve / veya başka birçok öğe içeriyorsa, genel performansı etkileyecektir. Bu kod parçası da yeniden düzenlenebilir.
Stas

@Stas Haklısınız, mantığı her biri kendi eylemlerinden ve davranışlarından sorumlu olan birden fazla görüntü denetleyicisi arasında bölmek daha iyidir
tf.alves

kapsayıcı görünümlerinin kullanılması, gezinme çubuğunda sorunlara yol açabilir. özellikle yarı saydam bir tane kullandığınızda. Tecrübelerime onun değil tavsiye çözüm
DamirDiz

45

Benim durumumda görüşlerim oldukça karmaşıktır ve farklı görünümlerin gizli özelliğini değiştiremem çünkü çok fazla hafıza kaplar.

Birkaç çözüm denedim ve bunların hiçbiri benim için işe yaramadı veya düzensiz bir şekilde, özellikle navBar'ın titleView özelliği, görünümleri basarken / açarken her zaman segmentedControl'ü göstermiyor.

Nasıl doğru şekilde yapılacağını açıklayan sorunla ilgili bu blog gönderisini buldum. Görünüşe göre bu çözümü bulmak için WWDC'2010'da Apple mühendislerinden yardım almış.

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

Bu bağlantıdaki çözüm, sorunla ilgili şu ana kadar bulduğum en iyi çözümü elden ele veriyor. Biraz ayarlamayla, altta bir tabbar ile de iyi çalıştı


Harika keşif için teşekkürler. Bu metodoloji için kesinlikle güzel ve zarif bir çözüm.
Shiun

1
Başarısız bir şekilde alttaki araç çubuğuyla bunun düzgün çalışmasını sağlamaya çalıştım, stackoverflow.com/questions/4748120/… Lütfen bana yardımcı olabilir misiniz?
Erik

Görünümler arasında yatay çevirme animasyonu yapmanın bir yolu var mı? Yoksa sadece animasyon olmadan mı çalışır?
aneuryzm

Evet, bu harika bir çözüm gibi görünüyor, ancak bunu, navigasyonControllers zaten içeride olan tabBarController ile çalışacak şekilde nasıl ayarlayabilirim?
Vladimir Stazhilov

2
Neyse ki, Container View Controller'ı uygulamak kusursuz bir şekilde çalıştı! Segmentler bile beklendiği gibi çalışıyor.
jweyrich

17

Veya bir tablo ise, tabloyu yeniden yükleyebilir ve cellForRowAtIndex'te, seçilen segment seçeneğine göre tabloyu farklı veri kaynaklarından doldurabilirsiniz.


7

Bir fikir, segmentli kontrollerin bulunduğu görünümün, farklı alt görünümlerle doldurduğunuz bir konteyner görünümüne sahip olmasıdır (segmentler değiştirildiğinde konteyner görünümünün tek bir alt görünümü olarak ekleyin). Bu alt görünümler için ayrı görünüm denetleyicileriniz bile olabilir, ancak ihtiyacınız olursa "viewWillAppear" ve "viewWillDisappear" gibi önemli yöntemleri iletmeniz gerekir (ve onlara hangi gezinme denetleyicisinin altında olduklarının söylenmesi gerekir).

Genel olarak bu oldukça iyi çalışıyor çünkü ana görünümü IB'deki kapsayıcıyla düzenleyebilirsiniz ve alt görünümler, kabın sahip oldukları boşluğu doldurur (otomatik yeniden boyutlandırma maskelerinizin doğru şekilde ayarlandığından emin olun).



2

@ Ronnie Liew cevabından şunu yaratıyorum:

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

.H atayın

 UISegmentedControl *lblSegChange;

- (IBAction)segValChange:(UISegmentedControl *) sender

.M beyan et

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

2

Swift versiyonu:

Üst görünüm denetleyicisi, her çocuk görüntüleme denetleyicisinin görünümünün boyutunu ve konumunu ayarlamaktan sorumludur. Alt görünüm denetleyicisinin görünümü, üst görünüm denetleyicisinin görünüm hiyerarşisinin bir parçası haline gelir.

Tembel özellikleri tanımlayın:

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

Çocuk Görünümü Denetleyicilerini Göster / Gizle:

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'i yönet

private func updateView() {
    if segmentedControl.selectedSegmentIndex == 0 {
        remove(asChildViewController: sessionsViewController)
        add(asChildViewController: summaryViewController)
    } else {
        remove(asChildViewController: summaryViewController)
        add(asChildViewController: sessionsViewController)
    }
}

Ve elbette çocuk görüntüleme denetleyicisi sınıflarınızda kullanabilirsiniz:

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

Referans: https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/


1
Bu bağlantı soruyu cevaplayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantıyı sağlamak daha iyidir. Bağlantılı sayfa değişirse yalnızca bağlantı yanıtları geçersiz hale gelebilir. - Yorumdan
Basile Perrenoud

2
@BasilePerrenoud Cevabı, çözümün en önemli ve en önemli kısmı ile güncelledik.
SlavisaPetkovic

1

Hızlı bir Swift Versiyonu:

@IBAction func segmentControlValueChanged(_ sender: UISegmentedControl) {

    if segmentControl.selectedSegmentIndex == 0 {

        // do something
    } else {

        // do something else
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.