Usuń tekst z przycisku Wstecz, zachowując ikonę

96

Chcę usunąć tekst z przycisku Wstecz, ale chcę zachować ikonę. próbowałem

let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton

Jednak powoduje to całkowite usunięcie tekstu i ikony.

lmiguelvargasf
źródło

Odpowiedzi:

99

Metoda @ rmd2 jest prawie poprawna, ale zamiast tego należy wybrać pasek nawigacyjny kontrolera, na który będzie wskazywał przycisk Wstecz, i wpisać " "w polu Przycisk Wstecz.

wprowadź opis obrazu tutaj

m8labs
źródło
1
najgorszy sposób, jeśli viewcontroller nie ma paska nawigacji to będę musiał dodać aby usunąć tekst
Daniel Beltrami
144

Wiem, że ma już odpowiedź, ale możesz to również zrobić w kodzie (na wypadek, gdybyś pracował ze stalówkami)

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

Dodaj powyższe w pierwszym kontrolerze widoku.

Zauważ, że musisz to zrobić dla każdego kontrolera widoku, który naciska. Więc jeśli masz 3 kontrolery widoku i chcesz usunąć tekst z tyłu z nich wszystkich, musisz dodać linię w kontrolerach widoku 1 i 2.

d9rad
źródło
5
To najlepsze rozwiązanie, jakie do tej pory widziałem, nie sprawia mi żadnych problemów
lostAtSeaJoshua
5
.Plainzostał zmieniony na .plain. Brak dużej litery p.
Gal
Idealny..! To jest to czego chce.
JD.
Najlepsze rozwiązanie. Dzięki.
Baran Emre
1
@ GastónAntonioMontes, to działa na iOS13, ale to bitowy licznik intuicyjne: pusty tytuł backBarButtonItem powinno zostać zgłoszone na pchanie kontrolera widoku, a nie wciśnięty jeden
Martin
51

Po wielu poszukiwaniach znalazłem najlepsze i proste rozwiązanie, wpłynie to na wszystkie kontrolery widoku napisane w Swift 4.2, a także działające w Swift 5

extension UIViewController {
    open override func awakeFromNib() {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }  
}
iOS Lifee
źródło
Welcome @ e.dimitrow
iOS Lifee
1
Działa jak urok
Jerry Oka na
5
Zauważ, że to będzie działać tylko wtedy, gdy ViewController jest zawarte w serii ujęć lub stalówka ...
Nathaniel Blumer
1
Genialne rozwiązanie!
WM
3
Kiedyś to działało, ale już nie (nadal działa na symulatorach iOS 12, tylko nie na najnowszym iOS 13) ...
tanya
37

Tekst przycisku Wstecz zależy od tytułu widoku głównego.

Sztuczka polega na tym, aby wyczyścić tytuł, jeśli widok główny zniknął, i ustawić go ponownie, jeśli zostanie ponownie wyświetlony:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // needed to clear the text in the back navigation:
    self.navigationItem.title = " "
}

override func viewWillAppear(_ animated: Bool) {
   
    super.viewWillAppear(animated)
    self.navigationItem.title = "My Title"
}
Stefan
źródło
33

Jeśli chcesz usunąć tytuł przycisku wstecz z popychane kontrolera widoku, powiedzmy, <Settingsaby <w subSettingsViewController wtedy masz ustawić backBarButtonItem tytuł SettingsViewController za viewWillDisappear () metody.

Cel C:

- (void)viewWillDisappear:(BOOL)animated
    [super viewWillDisappear:animated];
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
}

Szybki:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Muhammad Umair
źródło
1
.Plainzostał zmieniony na .plain. Brak dużej litery p.
Gal
1
Odpowiedź musi zostać zaktualizowana pod kątem zachowania elementu searchController. Na przykład, jeśli używasz oddzielnego resultsVC i stuknij w pozycji, która popycha kolejne VC metodę viewWillDisappear od początkowej searchController nie nazywa, stąd tytuł jest nadal istnieje
H4Hugo
To nie jest dobre podejście, jeśli szukasz rozwiązania dla ekranów w całej aplikacji. - Jeśli dodasz ten kod do jakiegoś "Base View Controller", viewWillDisappear pierwszego kontrolera widoku zostanie wywołany po viewDidAppear drugiego kontrolera widoku (gdzie zwykle ustawiasz tytuł) ... to zepsuje tytuły. Najlepszym sposobem jest nadpisanie przycisku Wstecz
Mithra Singam
Idealne rozwiązanie, dziękuję
SURESH SANKE,
28

Jeśli chcesz strzałkę wstecz, postępuj zgodnie z kodem umieszczonym w pliku AppDelegate w metodzie didFinishLaunchingWithOptions.

Dla Swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)
Pradeep Bishnoi
źródło
2
Podoba mi się ten, ponieważ możesz ujednolicić styl swojej aplikacji w jednym pliku i wywołać ją raz z poziomu delegata aplikacji
Aaronium112
4
To naprawdę fajne i szybkie rozwiązanie, ale ... może być trudne, jeśli masz inne przyciski paska oprócz tylnego
:)
3
Jedna uwaga, jeśli zaimplementujesz tylko atrybut „.normal”, zobaczysz tekst po kliknięciu. Dodaj tę samą linię dla „.selected”, „.highlighted” i „.disabled”. aby upewnić się, że nie widzisz migoczącego tekstu.
Nick N
1
Myślę, że będzie to miało efekt uboczny, inne przyciski paska oprócz przycisków wstecz również będą miały wpływ i będą miały wyraźny kolor tekstu :(
dhin
24

W moim przypadku, w przypadku niestandardowej ikony i tytułu, to załatwiło sprawę (Swift 4)

    let imgBack = UIImage(named: "ic_back")

    navigationController?.navigationBar.backIndicatorImage = imgBack
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBack

    navigationItem.leftItemsSupplementBackButton = true
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
Rafiqul Hasan
źródło
1
ostatnia linia w tym kodzie działała bez zarzutu. Wszystkie inne sugestie nie zadziałały, prawdopodobnie dlatego, że wszystkie moje kontrolery widoku są kontrolowane przez kontroler nawigacji. W takim przypadku navigationController? jest naprawdę potrzebne.
Salx
Będziesz potrzebował czterech górnych linii, jeśli chcesz dodać niestandardowy przycisk Wstecz. W przeciwnym razie ostatnia linia załatwi sprawę.
Rafiqul Hasan
14

Rozwiązałem ten problem, dodając znak „” w tytule StoryBoard poprzedniego ViewController. Tylko przestrzeń, a nie pusta; D.

wprowadź opis obrazu tutaj

rmd2
źródło
Potrzebuję poprzedniego ekranu, aby miał tytuł, więc myślę, że to nie zadziała.
lmiguelvargasf
2
Wyczyściłem ten tytuł, ale tytuł nadal pojawia się w tytule przycisku Wstecz
Himali Shah
1
nie czyść pola Tytuł, pole, wpisz „” (spację) w polu przycisku Wstecz
Kiril S.
13

Wreszcie znalazłem idealne rozwiązanie.

Po prostu dodaj jeden przezroczysty obraz i dodaj następujący kod w swoim AppDelegate.

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)
Lalit Kumar
źródło
1
To zdecydowanie najlepsza odpowiedź. Wcześniej korzystałem z UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustmenthackowania, które poleca większość innych odpowiedzi, ale na iPhonie X był zepsuty dla kontrolerów widoku z długimi tytułami. To rozwiązanie działa bez zarzutu.
Ned
3
Najlepsza odpowiedź. Działa lepiej niż przezroczysty kolor tekstu.
William T.
1
Najlepsze rozwiązanie z jakiego korzystałem przez ostatnie 4 lata! Robisz to raz, w jednym miejscu i dla wszystkich kontrolerów widoku !!!
korgx9
1
Kiedy próbowałem tego z iOS 12, tekst nadal pojawiał się obok obrazu. :(
Sean McMains
13

w szybkim 4

self.navigationController?.navigationBar.topItem?.title = ""
Amalendu Kar
źródło
Dzięki, pomogło mi (Swift 4.0, Xcode 10.1, iOS 12.1.1), dzięki
infinity_coding7
3
ALE, stracisz tytuł w rodzicielskim vc
Wei Lu
1
Jeśli obecny jest duży tytuł, topItem ma wartość largeTitle. Nie działa
Saranjith
11

To działa dla mnie

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
RomanV
źródło
1
Jeden poprawny. W iOS 13 navigationItem.backBarButtonItem nie działa. Zaoszczędziło mi to godzin wysiłku. Dzięki
Manish,
10

W przypadku Swift 4+ umieść te linie w AppDelegateatdidFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)      
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
BilalReffas
źródło
Po ustawieniu wyglądu w aplikacji delegata jasny kolor pierwszego planu jest dla każdego UIBarButtonItem, prawda? Więc jeśli dodam UIBarButtonItem z tekstem, czy muszę ręcznie zmienić kolor pierwszego planu dla tego przycisku?
kuzdu
1
To jest dobre, ale po naciśnięciu przycisku Wstecz nadal pokazuje tekst
William T.
To działa, ale uczynić inny przycisk bar znikają w iOS 11. Odpowiedź z Rafiqul Hasan powyżej może rozwiązać ten problem
huync
6

Jeśli masz ViewControllerA i chcesz przejść do ViewControllerB, w ViewControllerA, powinieneś ustawić bieżący navigationItem z nowym UIBarButtonItem i tytułem na ciąg z pustą spacją przed wypchnięciem do innego kontrolera widoku:

Ustaw tytuł jako ciąg z pustą spacją, nie możesz ustawić nil ani „” (pusty ciąg), ponieważ wartość domyślna to zero

let backItem = UIBarButtonItem()
backItem.title = " "
navigationItem.backBarButtonItem = backItem
let controllerB = ViewControllerB()
navigationController?.pushViewController(controllerB, animated: true)
Bradley
źródło
Otrzymywałem bardzo zabawne zachowanie z tekstem „Wstecz”, który pojawiał się ponownie, nawet gdy tytuł był ustawiony na „” (i sprawdzany jako taki) w ViewControllerB(nawet jeśli to zawsze działało do tej pory, w moim szczególnym przypadku), to było jedyne rozwiązanie, które zadziałało dla mnie
10623169
6

Umieść ten kod w każdym VC, który wypycha inny

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Polina Hill
źródło
3
let button: UIButton = UIButton (type: UIButtonType.Custom)
button.setImage(UIImage(named: "imageName"), forState: UIControlState.Normal)
button.addTarget(self, action: "backButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)

self.navigationItem.leftBarButtonItem = barButton

func backButtonPressed(btn : UIButton) {

    // Your code
}
Hasya
źródło
3

Aby usunąć ze wszystkich kontrolerów widoku w stosie kontrolerów nawigacji:

podklasę UINavigationController i dodaj to:

override func show(_ vc: UIViewController, sender: Any?) {
    setEmptyBackButton(vc)
    super.show(vc, sender: sender)
}

override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    setEmptyBackButton(viewController)
    super.pushViewController(viewController, animated: animated)
}

func setEmptyBackButton(_ viewController: UIViewController) {
    viewController.navigationItem.backBarButtonItem =
        UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Gaston Gonzalez
źródło
2

Czasami nie działa zmiana tylko koloru tytułu, w przypadku, gdy tytuł jest długi. Ponieważ może to spowodować przesunięcie tytułu paska nawigacji w lewo. Aby temu zapobiec, może być konieczne przesunięcie tytułu przycisku paska w poziomie, aby był on przezroczysty:

let barButtonItemAppearance = UIBarButtonItem.appearance()
    barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    barButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)
Max Niagolov
źródło
2

Detale

  • Xcode w wersji 10.2.1 (10E1001), Swift 5

Rozwiązanie

1. Utwórz niestandardową klasę UINavigationController

import UIKit

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

2. Dodaj rozszerzenie UIViewController

import UIKit

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

3. Zaktualizuj klasę ViewController

import UIKit

class ViewController: UIViewController {
    override var navigationItemBackButtonTextIsHidden: Bool { return true }
}

Pełna próbka

import UIKit

// MARK: - ViewController

class ViewController: UIViewController {

    var screenCounter = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        setupNavigationItem()
    }

    override var navigationItemBackButtonTextIsHidden: Bool { return (screenCounter % 2) == 0 }
}

extension ViewController {

    private func setupNavigationItem() {
        navigationItem.title = "VC \(screenCounter)"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "push", style: .plain, target: self, action: #selector(pushBarButtonTouchedUpInside))
    }

    @objc func pushBarButtonTouchedUpInside(button: UIBarButtonItem) {
        guard let navigationController = navigationController else { return }
        let viewController = ViewController()
        viewController.screenCounter = screenCounter + 1
        viewController.view.backgroundColor = .white
        navigationController.pushViewController(viewController, animated: true)
    }
}

// MARK: - NavigationController

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

// MARK: - UIViewController extension

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

Wynik

wprowadź opis obrazu tutaj

Wasilij Bodnarczuk
źródło
2

Możesz usunąć tekst z przycisku Wstecz za pomocą metody delegata UINavigationController.

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

}

extension CustomNavigationController: UINavigationControllerDelegate {
    
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: String(), style: .plain, target: nil, action: nil)
    }
    
}
keval
źródło
1

Dla mnie to załatwiło sprawę:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    self.navigationItem.title = " "
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationItem.title = "my amazing title"
    navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}

Zauważ, że jeśli tylko ustawić tytuł bez modyfikacji z backBarButtonItem będzie pojawiać do pracy. Ale jeśli spróbujesz wrócić za pomocą gestu, a następnie anulujesz i pozostaniesz na wciśniętym kontrolerze widoku, tytuł z powrotem wróci.

Praca w Swift 4

mrc
źródło
Czy możesz wytłumaczyć?
mrc,
Mam kontroler, który zawsze wyświetla tekst Wstecz z przyciskiem Wstecz. Tak więc powyższy kod nie działa w moim przypadku
Shahbaz Akram
1

Należy wybrać pasek nawigacyjny kontrolera, Z którego będzie wskazywał przycisk Wstecz i wpisać „” w polu Przycisk Wstecz.

np. jeśli pchasz kontroler A do kontrolera B, umieść spacje w pasku nawigacji kontrolera A.

Tushar Raikwar
źródło
1

Xcode 10, Swift 4+

Podobna odpowiedź do innych tutaj, ale warto zauważyć, że jeśli tekst nadal nie jest wyczyszczony, musisz kliknąć spację, a następnie Enter.

wprowadź opis obrazu tutaj

Aishat Olowoshile
źródło
1

Wypróbowałem kilka odpowiedzi i nie mogę ich zmusić do działania we wszystkich przypadkach. Jest to więc obejście, które nie wpływa na tytuł paska nawigacji, jeśli jest ustawiony.

    guard let items = viewController.navigationController?.navigationBar.items else { return }
    for item in items {
        if item.title == nil {
            item.title = ""
        }
    }
Rikard Platus
źródło
1

Jedną z alternatyw przesłonić wszystko ViewControllersdla mnie było rozszerzenie UINavigationControlleri ustawić backBarButtonItemz topViewController.

Swift 5 w Xcode 11.2.1:

extension UINavigationController {
    override open func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let backButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
        self.topViewController?.navigationItem.backBarButtonItem = backButton
    }
}
Nieszczęśliwy
źródło
1

Najłatwiejszym sposobem zrobienia tego programowo jest ustawienie backBarButtonItemz poziomu nadrzędnego kontrolera widoku (kontrolera, który wywołuje wypychanie).

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        navigationItem.backBarButtonItem = backBarButtonItem
    }
}

Więcej szczegółów tutaj https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/

sarunw
źródło
0

W Xcode 9.2 ze Swiftem działało tak:

override func viewWillDisappear(_ animated: Bool) {
   super.viewWillDisappear(true)
   navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Thiago Bueno
źródło
0

W przypadku, gdy w ogóle nie mamy kontroli nad poprzednim kontrolerem widoku (tj. Jeśli pracujemy w frameworku), możemy usunąć tytuł przycisku wstecz w następujący sposób:

// For iOS 10
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = String()

// For iOS 11
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = nil

To, co robi, to przejście do ostatniego elementu stosu nawigacji i usunięcie jego wstecznego tytułu. Pamiętaj, aby zapisać oryginalny, gdy pojawi się nasz kontroler widoku:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    originalBackButtonTitle = navigationController?.navigationBar.items?.last?.backBarButtonItem?.title
    // Delete title somewhere here...
}

a następnie przydziel go ponownie, aby nie zakłócać żadnej części aplikacji:

override func viewWillDisappear(_ animated: Bool) {
    navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = originalBackButtonTitle
    super.viewWillDisappear(animated)
}
Ángel Téllez
źródło
0

To rozwiąże Twój problem:

    import UIKit

    extension UINavigationController{

    func customizeBackArrow(){
        let yourBackImage = UIImage(named: "icon_back_arrow")
        self.navigationBar.backIndicatorImage = yourBackImage
        self.navigationBar.tintColor = Common.offBlackColor
        self.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
        navigationItem.leftItemsSupplementBackButton = true
        self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", 
           style: .plain, target: self, action: nil)

    }
}
mossman252
źródło
0

Łatwym sposobem programistycznym, bez niepożądanych efektów ubocznych, jest zainicjowanie navigationItem.backBarButtonItem z pustym elementem w metodzie awakeFromNib kontrolera źródłowego (tego, z którego nawigujesz):

override func awakeFromNib() {
    super.awakeFromNib()
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

Uwaga: Jeśli później zainicjowałeś przycisk Wstecz, tak jak w metodzie viewDidLoad () , stracisz funkcję swipe-back (przesunięcie od lewej krawędzi do prawej powoduje cofnięcie się o jeden krok w stosie nawigacji).

Następnie, jeśli chcesz mieć różne teksty przycisku Wstecz dla różnych kontrolerów docelowych i jeśli używasz segue , możesz ustawić tytuł w metodzie Przygotuj (dla segue :, nadawca :) , na przykład:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let item = navigationItem.backBarButtonItem {
        switch segue.identifier {
        case "SceneOne": item.title = "Back"; break
        case "SceneTwo": item.title = "Home"; break
        case "SceneThree": item.title = nil; break // Use this scene's title
        default: item.title = "" // No text
        }
    }
}
Jiri Volejnik
źródło