ข้อความที่กำหนดเอง UINavigationController“ ปุ่มย้อนกลับ”?


147

ปุ่ม "ย้อนกลับ" ของUINavigationControllerโดยค่าเริ่มต้นจะแสดงชื่อของมุมมองล่าสุดในสแต็ก มีวิธีที่จะมีข้อความที่กำหนดเองในปุ่มย้อนกลับแทนหรือไม่?


1
งานนี้สำหรับฉันself.navigationController.navigationBar.topItem.title = @"Custom text";
huync

คำตอบ:


342

จากลิงค์นี้ :

self.navigationItem.backBarButtonItem =
   [[UIBarButtonItem alloc] initWithTitle:@"Custom Title"
            style:UIBarButtonItemStylePlain
           target:nil
           action:nil];

ดังที่ไทเลอร์กล่าวไว้ในความคิดเห็น:

อย่าทำสิ่งนี้ในตัวควบคุมมุมมองที่มองเห็นได้ แต่ในตัวควบคุมมุมมองที่คุณเห็นว่าคุณกดปุ่มย้อนกลับ


4
คุณควร releaseUIBarButtonItem
Mehrdad Afshari

217
นอกจากนี้โปรดทราบว่าคุณต้องทำสิ่งนี้ในมุมมองคอนโทรลเลอร์หนึ่งระดับขึ้นไปบนสแต็ก ในคำอื่น ๆ อย่าทำเช่นนี้ในตัวควบคุมมุมมองที่มองเห็น แต่ในตัวควบคุมมุมมองที่คุณจะเห็นว่าคุณกดปุ่มย้อนกลับ
Tyler

6
เพียงเพื่อชี้แจงความคิดเห็นของไทเลอร์เพราะฉันไม่เข้าใจสิ่งนี้ในตอนแรก: การตั้งค่า backBarButtonItem ในตัวควบคุมมุมมอง navigationItem กำลังตั้งค่าปุ่มที่จะแสดงเพื่อให้ได้กลับไปที่ตัวควบคุมมุมมองนี้ โปรดทราบว่าแม้ว่าจะไม่มีรูปแบบปุ่มสำหรับปุ่มลูกศรปุ่มนี้จะรับสไตล์ลูกศรอยู่ดี ฉันใช้ UIBarButtonItemStylePlain และยังคงใช้รูปแบบปุ่มลูกศร
Jon Steinmetz

3
คำแนะนำ: แทนที่จะถือว่าสไตล์ผ่านสไตล์ที่ตั้งไว้ในปัจจุบัน ในรหัสของคำตอบนี้แทนด้วยการเรียกร้องให้สถานที่ให้บริการUIBarButtonItemStyleBordered self.navigationItem.backBarButtonItem.styleเอกสารประกอบ: developer.apple.com/library/ios/documentation/uikit/reference/
......

1
โปรดทราบว่าภายใต้ ARC คุณต้องออกจากการโทรอัตโนมัติ ดังนั้นคุณมี self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @ สไตล์ "ชื่อที่กำหนดเอง": UIBarButtonItemStyleBordered เป้าหมาย: ไม่มีการกระทำ: ไม่มี]
bkbeachlabs

43

คุณสามารถตั้งค่าข้อความในเครื่องมือสร้างส่วนต่อประสาน:

เลือกรายการการนำทางของ ViewController ที่ปุ่มย้อนกลับจะกลับไปที่:

ป้อนคำอธิบายรูปภาพที่นี่

ในตัวตรวจสอบแอ็ตทริบิวต์ของแผงเครื่องมือให้ป้อนชื่อของคุณสำหรับปุ่มย้อนกลับ

ป้อนคำอธิบายรูปภาพที่นี่

ฉันต้องการวิธีนี้มากกว่าการตั้งชื่อเป็นรหัสในคำตอบที่ยอมรับ

นอกจากนี้โปรดทราบว่าคุณต้องทำสิ่งนี้ในมุมมองคอนโทรลเลอร์หนึ่งระดับขึ้นไปบนสแต็ก ในคำอื่น ๆ อย่าทำเช่นนี้ในตัวควบคุมมุมมองที่มองเห็น แต่ในตัวควบคุมมุมมองที่คุณจะเห็นว่าคุณกดปุ่มย้อนกลับ
--Tyler


นี่คือคำตอบที่ดีที่สุดที่ฉันพบ
Ayan Sengupta

2
เพื่อความชัดเจนต้องตั้งค่านี้ในรายการการนำทางของตัวควบคุมมุมมองไม่ใช่ตัวตรวจสอบคุณลักษณะของตัวควบคุมมุมมอง
Patrick อ่าน

นี่คือคำตอบที่ดีที่สุดที่ฉันพบ
bicepjai

นี่คือคำตอบที่ดีที่สุด
Alex Brown

2
ในฐานะของ Xcode 6.1.1 และทำงานใน iOS 7 ดูเหมือนว่าชื่อมุมมองก่อนหน้าของคุณจะยังคงแทนที่ชื่อปุ่มย้อนกลับที่คุณตั้งไว้ที่นี่ หากหัวเรื่องของมุมมองก่อนหน้ามีจำนวนเกินขีด จำกัด 11 ตัวอักษรปุ่มย้อนกลับของมุมมองถัดไปจะพูดว่า "ย้อนกลับ" ไม่มีทางที่จะทำได้ยกเว้นการสร้างรายการแถบนำทางใหม่ตั้งแต่ต้นดังแสดงในคำตอบที่ได้รับการโหวตสูงสุดที่นี่
เรย์

22

ฉันใช้สิ่งนี้:

// In the current view controller, not the one that is one level up in the stack
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.navigationBar.backItem.title = @"Custom text";
}

สิ่งนี้เกือบจะได้ผลสำหรับฉัน แต่เมื่อฉันคลิกปุ่มย้อนกลับข้อความจะเปลี่ยนกลับไปเป็นชื่อของผู้ปกครองในช่วงระยะเวลาของภาพเคลื่อนไหว :-(
Danny Tuppeny

3
สิ่งนี้จะเปลี่ยนชื่อปุ่มย้อนกลับของคอนโทรลเลอร์ขึ้นในสแต็ก มันไม่เปลี่ยนชื่อปุ่มย้อนกลับของตัวควบคุมที่แสดงอยู่ในปัจจุบัน ยิ่งแย่ไปกว่า: มันเปลี่ยนชื่อของคอนโทรลเลอร์ก่อนหน้านี้เป็นคอนโทรลเลอร์ก่อนหน้า!
leviathan

ตามที่ระบุไว้โดยผู้แสดงความคิดเห็นอื่น ๆ วิธีการนี้จะไม่สามารถป้องกันได้เล็กน้อย ฉันจะไม่แนะนำให้ทำเช่นนี้เพราะมันไม่ใช่วิธีที่ API ตั้งใจให้คุณใช้งาน คุณสามารถตั้งค่าตัวเองสำหรับข้อบกพร่องที่ยากในอนาคต!
RickDT

11

ฉันพบวิธีแก้ปัญหาที่ใช้งานง่ายเพียงแค่ตั้งชื่อของคอนโทรลเลอร์ก่อนที่จะดันคอนโทรลเลอร์อื่นลงบนสแต็กดังนี้:

self.navigationItem.title = @"Replacement Title";
[self.navigationController pushViewController:newCtrl animated:YES];

จากนั้นตรวจสอบให้แน่ใจว่าได้ตั้งชื่อดั้งเดิมไว้viewWillAppearเช่นนี้

-(void)viewWillAppear:(BOOL)animated
{
  ...
  self.navigationItem.title = @"Original Title";
  ...
}

สิ่งนี้ทำงานได้เนื่องจากพฤติกรรมเริ่มต้นของUINavigationControllerเมื่อสร้างปุ่มย้อนกลับในระหว่างการดำเนินการผลักดันคือการใช้ชื่อจากตัวควบคุมก่อนหน้านี้


1
ปัญหานี้คือการเปลี่ยนแปลงชื่อเรื่องในมุมมองเก่าตามที่มันเคลื่อนไหวและดูเล็กน้อย ดูเหมือนว่าจะไม่มีวิธีแก้ปัญหาใด ๆ ที่ได้ผลตามที่คุณต้องการ :-(
Danny Tuppeny

1
นี่คือสถานการณ์ที่สมบูรณ์แบบของฉันเพราะฉันไม่แสดง NavBar บนหน้าจอก่อนหน้าและฉันต้องการลบ titleLabel ออกจากปุ่มย้อนกลับบนหน้าจอใหม่และมีลูกศรบั้ง iOS7 ดังนั้นฉันสามารถตั้งค่าตัวอักษร NSString ที่ว่างเปล่าสำหรับชื่อเรื่องได้
siburb

การควบคุมมุมมองผลักยกข้อยกเว้นเมื่อแตะที่ด้านหลัง
Sumit

7

หัวเรื่องของปุ่มย้อนกลับเป็นค่าเริ่มต้นของชื่อมุมมองก่อนหน้าดังนั้นเคล็ดลับที่รวดเร็วที่ฉันใช้คือการวางรหัสต่อไปนี้ลงในไฟล์. m ของมุมมองก่อนหน้า

-(void)viewWillAppear:(BOOL)animated {

    // Set title
    self.navigationItem.title=@"Original Title";
}

-(void)viewWillDisappear:(BOOL)animated {

    // Set title
    self.navigationItem.title=@"Back";
}

วิธีนี้ใช้ได้ผลดีสำหรับหลาย ๆ กรณีและมันค่อนข้างง่าย ... การสังเกตเพียงอย่างเดียวคือการเอาชนะวิธีใดวิธีหนึ่งเหล่านี้ต้องการให้มีการเรียกใช้การดำเนินการของ super ในบางจุดในวิธีการใหม่
izk

2
ด้วยวิธีนี้เราจะสังเกตเห็นชื่อของมุมมองพาเรนต์ที่เปลี่ยนเป็น 'ย้อนกลับ' ก่อนที่จะมีภาพเคลื่อนไหวแบบพุช (และ, sorta sucks, ว่าถ้าคุณย้ายสิ่งนี้ไปยังวิธีการ viewDidDisappear, คุณจะเห็นสวิตช์เกิดขึ้นหลังจากการกด .. )
James Boutcher

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

ในขณะที่คำตอบที่stackoverflow.com/questions/1441699/..รู้สึกว่าต้องการการปรับแต่งมากกว่าที่จำเป็นมันเป็นวิธีการจัดทำเอกสารและที่สำคัญดูเหมือนว่าจะสอดคล้องกับความตั้งใจของเรามากขึ้น
trss

6

ในวิธีการเริ่มต้นของคุณเพิ่มรหัสต่อไปนี้:

- (id)initWithStyle:(UITableViewStyle)style {
    if(self = [super init]) {

        //...

        UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" 
                                             style:UIBarButtonItemStylePlain 
                                            target:self 
                                            action:@selector(goBack)];
        self.navigationItem.leftBarButtonItem = customBackButton;
        [customBackButton release];

        //...
    }
    return self;
}

จากนั้นเพิ่มวิธีการง่าย ๆ เพื่ออนุญาตให้มีการยกเลิก viewview

-(void)goBack {
    [self.navigationController popViewControllerAnimated:YES];  
}

3

เพิ่มรหัสต่อไปนี้ใน viewDidLoad หรือ loadView

self.navigationController.navigationBar.topItem.title = @"Custom text";

ฉันทดสอบใน iPhone และ iPad ด้วย iOS 9


ควรเป็น self.navigationController? .navigationBar.backItem? .title = "ข้อความที่กำหนดเอง"
Peacemoon

1
ข้อแตกต่างที่ฉันต้องการคือการผูกมัดตัวเลือกกับnavigationControllerและtopItemคุณสมบัติเช่น:self.navigationController?.navigationBar.topItem?.title = "Custom Text"
Bulwinkel

2

การเพิ่มคำตอบของบังเหียน หมายเหตุจากเอกสารของ Apple ที่ประกาศของbackBarButtonItemคือ:

@property(nonatomic, retain) UIBarButtonItem *backBarButtonItem

ดังนั้นคำตอบของ rein จะทำให้หน่วยความจำรั่วเพราะตัวตั้งค่าที่สังเคราะห์จะretainเป็นอินสแตนซ์ที่คุณส่งผ่านซึ่งจะไม่ถูกปล่อยออกมาอย่างชัดเจน คุณสามารถแก้ไขได้โดยใช้autorelease

 self.navigationItem.backBarButtonItem = 
      [[[UIBarButtonItem alloc] initWithTitle:@"Custom Title" 
         style:UIBarButtonItemStyleBordered
         target:nil
         action:nil] autorelease];  //<-- autoreleased

หรือคุณอาจชี้ตัวแปรไปที่อินสแตนซ์เพื่อให้คุณสามารถเผยแพร่ได้ในภายหลัง:

UIBarButtonItem* item = ...
self.navigationItem.backBarButtonItem = item;
[item release];

หวังว่านี่จะช่วยได้!


หมายเหตุวันนี้กับ ARC คุณไม่จำเป็นต้องกังวลเกี่ยว autorelease (และแน่นอนเรียบเรียงจะผิดพลาดถ้าคุณพยายามที่จะ autorelease ในโครงการ ARC เปิดใช้งาน)
เอริคโกลด์เบิร์ก

2
- (void)viewDidLoad {
  [super viewDidLoad];

  UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
  self.navigationItem.backBarButtonItem = backButton;
  [backButton release];
}

2

ฉันค้นพบสิ่งที่น่าสนใจ หากคุณ subclass UINavigationControllerและแทนที่pushViewController:animated:วิธีและทำสิ่งนี้: (จำไว้ว่าฉันใช้ ARC)

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 
 initWithTitle: @"Back" 
 style: UIBarButtonItemStyleBordered
 target: nil action: nil];

viewController.navigationItem.backBarButtonItem = backButton;

[super pushViewController:viewController animated:animated];

จากนั้นสำหรับทุกสิ่งViewControllersที่ถูกผลักด้วยตัวควบคุมการนำทางของคุณจะมีปุ่ม "ย้อนกลับ" ในนั้นโดยอัตโนมัติ หากคุณต้องการเปลี่ยนข้อความสำหรับตัวควบคุมมุมมองบางตัวคุณสามารถลองและอาจส่งตัวควบคุมวิวไปยังคลาสที่แน่นอนหรือโปรโตคอลที่คุณกำหนดเองได้ (ซึ่งตัวควบคุมวิวเวอร์ของคุณสืบทอดมาซึ่งอาจมีวิธีเช่นbackButtonTextหรืออะไรทำนองนั้น) ข้อมูลบางอย่างเกี่ยวกับ viewcontroller ที่มาใน sothat คุณสามารถปรับแต่งข้อความปุ่มย้อนกลับได้ ตอนนี้ข้อความปุ่มย้อนกลับได้รับการดูแลในสถานที่ที่ควรรับผิดชอบ แต่เพียงผู้เดียว ฉันต้องยอมรับว่าการสร้างปุ่มใหม่เพื่อเปลี่ยนข้อความ sucks แต่ก็ดี

มีใครคิดบ้างไหมว่าทำไมไม่ทำอย่างนี้? อย่างน้อยคุณไม่ต้องเล่นซอกับชื่อ viewcontroller หรือต้องจำไว้ว่าให้สร้างปุ่มย้อนกลับใหม่ก่อนที่จะผลักดัน viewcontroller บนตัวควบคุมทิศทาง


0

คำตอบของบังเหียนทำงานได้ดี

โปรดทราบว่าหากคุณผลักดันตัวควบคุมมุมมองมากกว่าหนึ่งตัวชื่อของปุ่มย้อนกลับที่เปลี่ยนไปจะปรากฏขึ้นสำหรับแต่ละตัวควบคุมซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ

ในกรณีดังกล่าวคุณจะต้องสร้าง UIBarButtonItem ที่กำหนดเองทุกครั้งที่คุณกดตัวควบคุมมุมมอง

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


0

ตามข้อเสนอแนะของ Aubrey คุณสามารถทำได้ในตัวควบคุมมุมมองลูก:

สร้างตัวแปรสองตัวสำหรับเก็บค่าเก่าของ navigationItem.title ของพาเรนต์และ navigationItem ของพาเรนต์

UINavigationItem* oldItem;
NSString* oldTitle;

ในviewDidLoadเพิ่มต่อไปนี้:

oldItem = self.navigationController.navigationBar.topItem;  
oldTitle = oldItem.title;  
[oldItem setTitle: @"Back"];  

ในviewWillDisappearเพิ่มต่อไปนี้:

[oldItem setTitle: oldTitle];  
oldTitle = nil;  // do this if you have retained oldTitle
oldItem = nil;   // do this if you have retained oldItem

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


0

ใส่สิ่งนี้ลงในตัวคุณviewDidLoadโดยหวังว่ามันจะส่งผลต่อสิ่งที่คุณกำลังมองหา

UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" 
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];

0

ถ้าคุณต้องการตั้งชื่อใน ARRIVING controller (บางครั้งตรรกะมากกว่า .. ) ใน swift 3 ทำได้:

func setBackButtonNavBar(title: String, delay: Double){

    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in

        if let navBar = self.navigationController?.navigationBar{
            navBar.backItem?.title = title
        }
    })

}

ในตัวควบคุมที่กำลังจะมาถึง:

override func viewDidLoad() {
    super.viewDidLoad()
    self.setBackButtonNavBar(title: "back", delay: 0.3)
}

ฉันมักจะใส่ self.setBackButtonNavBar ในส่วนขยายของตัวควบคุม


0

ฉันรู้ว่านี่เป็นคำถามเก่าและชนิดของคำตอบที่ได้รับการปรับปรุง!

วิธีง่ายๆในการทำเช่นนี้ในผู้ปกครอง ViewController:

เช่นที่จะนำคุณไปยังตัวควบคุมมุมมองถัดไป

self.navigationItem.backBarButtonItem  = UIBarButtonItem(title: "Custom text here", style: .plain, target: nil, action: nil)

-1

UINavigationConrollerการทำเช่นนี้ในรหัสเอารูปแบบปุ่มด้านหลังของ StoryBoardถ้าคุณเพิ่มรายการนำทางในแต่ละมุมมองของคุณคุณสามารถตั้งชื่อของปุ่มย้อนกลับไปในที่

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