เปลี่ยนเป็นมุมมองแท็บ TabBar โดยทางโปรแกรมหรือไม่


159

สมมติว่าผมมีUIButtonในมุมมองแท็บหนึ่งใน app iPhone TabBarControllerของฉันและฉันต้องการที่จะมีมันเปิดแท็บที่แตกต่างกันในแถบแท็บของ ฉันจะเขียนรหัสเพื่อทำสิ่งนี้ได้อย่างไร

ฉันสมมติว่าฉันยกเลิกการโหลดมุมมองที่มีอยู่และโหลดมุมมองแท็บเฉพาะ แต่ฉันไม่แน่ใจว่าจะเขียนโค้ดอย่างไร


ฉันมีปัญหากับวิธีการข้างต้นพวกช่วยใน [คำถาม] [1] [1]: stackoverflow.com/questions/19742416//
Roman Simenok

คำตอบ:


399

ลองใช้รหัสนี้ใน Swift หรือ Objective-C

รวดเร็ว

self.tabBarController.selectedIndex = 1

Objective-C

[self.tabBarController setSelectedIndex:1];

8
โปรดทราบว่าหากดัชนีแมปไปยังแท็บภายในตัวควบคุมมุมมองเพิ่มเติม (หากคุณมีแท็บมากกว่าห้าแท็บ) สิ่งนี้จะไม่ทำงาน -setSelectedViewController:ในกรณีที่ใช้
Joe D'Andrea

หลังจากฉันทำเช่นนี้และเปลี่ยนแท็บสำเร็จฉันไม่สามารถเลือกแถบแท็บได้ตามปกติ UPDATE: สิ่งนี้เกี่ยวข้องกับฉันที่เรียกว่า popToRootViewController ทันทีก่อนที่ฉันจะสลับแท็บโดยทางโปรแกรม
Adam Johns

แต่ Self จะไม่ทำงานถ้าฉันต้องการเปลี่ยนแท็บ สมมติว่าฉันคลิกแท็บ 3 และแสดง alertView ทันทีในฐานะผู้ใช้กดตกลงฉันต้องการเปลี่ยนไปที่แท็บ 1 อีกครั้ง ตนเองจะไม่ถูกต้องเนื่องจากไม่ใช่วัตถุปัจจุบัน ถูกต้องหรือไม่
Alix

มันใช้งานได้ดี แต่ฉันก็ต้องส่งข้อมูลในขณะที่สลับแท็บด้วย ฉันมีป้ายกำกับในแท็บที่ฉันสลับไปที่จำเป็นต้องได้รับการอัปเดตทันทีที่ฉันเปลี่ยนแท็บ! มีวิธีแก้ไขปัญหานี้อย่างไร?
Md Rais

@AdamJohns คุณจัดการกับปัญหาของคุณได้อย่างไร เพื่อให้ทำงานเหมือนแท็บดั้งเดิม มันควรจะปรากฏขึ้นที่ rootViewController เมื่อคลิกครั้งที่สอง
Waqas

20

โปรดทราบว่าแท็บจะได้รับการจัดทำดัชนีเริ่มต้นจาก 0 ดังนั้นข้อมูลโค้ดต่อไปนี้จึงใช้งานได้

tabBarController = [[UITabBarController alloc] init];
.
.
.
tabBarController.selectedViewController = [tabBarController.viewControllers objectAtIndex:4];

ไปที่แท็บที่ห้าในแถบ


12

ความคิดเห็นของฉันคือselectedIndexหรือการใช้objectAtIndexไม่จำเป็นต้องเป็นวิธีที่ดีที่สุดในการเปลี่ยนแท็บ หากคุณเรียงลำดับแท็บใหม่การเลือกดัชนีที่กำหนดรหัสแบบยากอาจทำให้เกิดปัญหากับพฤติกรรมการใช้งานแอปในอดีตของคุณ

หากคุณมีการอ้างอิงวัตถุของตัวควบคุมมุมมองที่คุณต้องการเปลี่ยนเป็นคุณสามารถทำ:

tabBarController.selectedViewController = myViewController

แน่นอนคุณต้องให้แน่ใจว่ามันอยู่ในรายการของmyViewControllertabBarController.viewControllers


ฉันจำเป็นต้องเลือกเพิ่มเติม NavController และเป็นวิธีเดียวที่จะทำเช่นนั้นเท่าที่ฉันรู้
Ossir

9

คุณสามารถตั้งค่าselectedIndexคุณสมบัติบน UITabBarController เป็นดัชนีที่เหมาะสมได้และมุมมองจะเปลี่ยนไปเช่นเดียวกับที่ผู้ใช้กดปุ่มแท็บ


6
ด้วยข้อแตกต่างเล็ก ๆ น้อย ๆ อย่างหนึ่งคือวิธีการมอบหมายที่สามารถแจ้งแท็บการสับเปลี่ยนผู้ใช้ไม่ได้ถูกเรียก
แบรด The App Guy

3
การตั้งค่าselectedIndexไม่ทำงานสำหรับฉันด้วยดัชนี> 4 แต่selectedViewControllerทำได้
bugloaf

3

ฉันลองสิ่งที่ดิสโก้ S2 แนะนำอยู่ใกล้ แต่นี่คือสิ่งที่ทำให้ฉันทำงานได้ สิ่งนี้ถูกเรียกใช้หลังจากทำการกระทำภายในแท็บอื่นเสร็จสิ้น

for (UINavigationController *controller in self.tabBarController.viewControllers)
{
    if ([controller isKindOfClass:[MyViewController class]])
    {
        [self.tabBarController setSelectedViewController:controller];
        break;
    }
}

2

สำหรับกรณีที่คุณอาจจะย้ายแท็บนี่คือรหัสบางส่วน

for ( UINavigationController *controller in self.tabBarController.viewControllers ) {
            if ( [[controller.childViewControllers objectAtIndex:0] isKindOfClass:[MyViewController class]]) {
                [self.tabBarController setSelectedViewController:controller];
                break;
            }
        }

2

เช่นเดียวกับโซลูชันของ Stuart Clark แต่สำหรับ Swift 3:

func setTab<T>(_ myClass: T.Type) {
    var i: Int = 0
    if let controllers = self.tabBarController?.viewControllers {
        for controller in controllers {
            if let nav = controller as? UINavigationController, nav.topViewController is T {
                break
            }
            i = i+1
        }
    }
    self.tabBarController?.selectedIndex = i
}

ใช้มันแบบนี้:

setTab(MyViewController.self)

โปรดทราบว่าแท็บตัวควบคุมของฉันเชื่อมโยงไปยังมุมมองตัวควบคุมที่อยู่เบื้องหลังระบบนำทางตัวควบคุม หากไม่มีการนำทางตัวควบคุมมันจะมีลักษณะเช่นนี้:

if let controller is T {

ไม่มีตัวควบคุมการนำทาง: func selectViewController <ViewControllerModel> (ประเภท: ViewControllerModel.Type) {self.selectedViewController = self.viewControllers?. ลำดับแรก (โดยที่: {viewController ใน viewController เป็นรุ่นที่ ViewControllerModel})}
dev_exo

1

ฉันต้องการที่จะสามารถระบุแท็บที่แสดงโดยคลาสแทนที่จะเป็นดัชนีเพราะฉันคิดว่ามันสร้างขึ้นมาสำหรับโซลูชันที่มีประสิทธิภาพซึ่งขึ้นอยู่กับว่าคุณใช้วิธีเชื่อมโยง IB อย่างไร ฉันไม่พบวิธีแก้ปัญหาของดิสโก้หรือ Joped อย่างใดอย่างหนึ่งดังนั้นฉันจึงสร้างวิธีนี้:

-(void)setTab:(Class)class{
    int i = 0;
    for (UINavigationController *controller in self.tabBarContontroller.viewControllers){
        if ([controller isKindOfClass:class]){
            break;
        }
        i++;
    }
    self.tabBarContontroller.selectedIndex = i;
}

คุณเรียกว่าแบบนี้:

[self setTab:[YourClass class]];

หวังว่านี่จะเป็นประโยชน์กับใครบางคน


มันใช้งานได้ดีมาก! ฉันเขียนใหม่สำหรับ Swift3 ในคำตอบอื่น
Json

1

ปัญหาของฉันแตกต่างกันเล็กน้อยฉันต้องเปลี่ยนจาก childViewController หนึ่งตัวในแท็บที่ 1 ไปที่บ้านดูที่ตัวควบคุมของแท็บที่สอง ฉันใช้โซลูชันที่มีให้ในชั้นบน:

tabBarController.selectedIndex = 2

อย่างไรก็ตามเมื่อเปลี่ยนเป็นหน้าแรกของแถบที่ 2 แถบเนื้อหาจะไม่ปรากฏ และเมื่อฉันดีบัก viewDidAppear, viewWillAppear, viewDidLoad จะไม่เรียกสิ่งเหล่านี้ โซลูชันของฉันคือการเพิ่มรหัสต่อไปนี้ใน UITabBarController:

override var shouldAutomaticallyForwardAppearanceMethods: Bool 
{
    return true
}

0

ใช้ในAppDelegate.mไฟล์:

(void)tabBarController:(UITabBarController *)tabBarController
 didSelectViewController:(UIViewController *)viewController
{

     NSLog(@"Selected index: %d", tabBarController.selectedIndex);

    if (viewController == tabBarController.moreNavigationController)
    {
        tabBarController.moreNavigationController.delegate = self;
    }

    NSUInteger selectedIndex = tabBarController.selectedIndex;

    switch (selectedIndex) {

        case 0:
            NSLog(@"click me %u",self.tabBarController.selectedIndex);
            break;
        case 1:
            NSLog(@"click me again!! %u",self.tabBarController.selectedIndex);
            break;

        default:
            break;

    }

}

0

เช่นเดียวกับโซลูชันของ Stuart Clark แต่สำหรับ Swift 3 และการใช้ตัวระบุการเรียกคืนเพื่อค้นหาแท็บที่ถูกต้อง:

private func setTabById(id: String) {
  var i: Int = 0
  if let controllers = self.tabBarController?.viewControllers {
    for controller in controllers {
      if let nav = controller as? UINavigationController, nav.topViewController?.restorationIdentifier == id {
        break
      }
      i = i+1
    }
  }
  self.tabBarController?.selectedIndex = i
}

ใช้อย่างนี้ ("มนุษย์" และ "หุ่นยนต์" ต้องตั้งค่าไว้ในกระดานเรื่องราวสำหรับ viewController เฉพาะและเป็นรหัสการคืนค่าหรือใช้สตอรีบอร์ด ID และทำเครื่องหมาย "ใช้สตอรีบอร์ด ID" เป็นรหัสการเรียกคืน):

struct Tabs {
    static let Humans = "Humans"
    static let Robots = "Robots"
}
setTabById(id: Tabs.Robots)

โปรดทราบว่าแท็บตัวควบคุมของฉันเชื่อมโยงไปยังมุมมองตัวควบคุมที่อยู่เบื้องหลังระบบนำทางตัวควบคุม หากไม่มีการนำทางตัวควบคุมมันจะมีลักษณะเช่นนี้:

if controller.restorationIdentifier == id {

0
import UIKit

class TabbarViewController: UITabBarController,UITabBarControllerDelegate {

//MARK:- View Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

//Tabbar delegate method
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController
    yourView.popToRootViewController(animated:false)
}



}

1
โดยปกติแล้วจะเป็นการดีกว่าที่จะอธิบายวิธีแก้ปัญหาแทนที่จะเพียงแค่โพสต์แถวของรหัสที่ไม่ระบุชื่อ คุณสามารถอ่านฉันจะเขียนคำตอบที่ดีได้อย่างไรและอธิบายคำตอบที่อิงกับรหัสทั้งหมด
Anh Pham
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.