Немає проведення пальцем назад, коли приховуєте панель навігації в UINavigationController


86

Мені подобається пакет розгорток, який успадкував від вбудовування ваших поглядів у UINavigationController. На жаль, я, здається, не можу знайти спосіб приховати, NavigationBarале все ж таки сенсорною панеллю проведіть пальцем назад gesture. Я можу писати власні жести, але я вважаю за краще не робити цього і покладатися на UINavigationControllerзворотне проведення пальцем gesture.

якщо я знімаю прапорець у розкадровці, зворотне проведення не працює

введіть тут опис зображення

в іншому випадку, якщо я програмно це приховую, той самий сценарій.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.navigationController setNavigationBarHidden:YES animated:NO]; // and animated:YES
}

Чи неможливо приховати верхню частину NavigationBarі все одно провести пальцем?


1
Чи допустимо додавання UIGestureRecognizer? Це легкий вітер для реалізації.
SwiftArchitect

1
@LancelotdelaMare, я намагався цього уникнути, оскільки це не буде працювати так гладко, як зворотний рух UINavigationController. Я розглядаю UIScreenEdgePanGestureRecognizer, оскільки деякі люди кажуть, що це допомагає, але ще не змусило його працювати. Шукаєте тут найпростіше та найелегантніше рішення.
mihai

Відповіді:


96

Працюючий хак полягає в тому, щоб встановити interactivePopGestureRecognizerделегата ', UINavigationControllerщоб nilвподобати це:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

Але в деяких ситуаціях це може створити дивні ефекти.


16
"Повторне проведення пальцем назад може спричинити розпізнавання жесту, коли у стеку є лише один контролер перегляду, який, у свою чергу, перетворює інтерфейс користувача (я вважаю це несподівано для інженерів UIKit), де він перестає розпізнавати будь-які жести"
HorseT

4
Альтернатива , яка може захистити від несподіваного стану було б встановити його на який - небудь об'єкт низького рівня (я використовував моє додаток делегата) і здійснити gestureRecognizerShouldBegin, повертаючись , trueякщо navigationController«s viewControllerрахунки більше 0.
Kenny Уінкер

4
Хоча це працює, ВИСОКО рекомендую проти цього. Поломка делегата спричинила рідкісний і важкий для ідентифікації головний блок потоку. Виявляється, це не основний блок потоку, а той, що описав @HorseT.
Джош Бернфельд,

3
Мій додаток зберігає дескриптор делегування, а потім відновлює його, viewWillDisappearі до цього часу не відчував негативних побічних ефектів.
Дон Парк

1
!!!! Дуже не рекомендуємо використовувати це рішення, коли при багаторазовому використанні пальців виникає дивна поведінка, спина відключена, і ціла програма більше не реагує
KarimIhab

79

Проблеми з іншими методами

Встановлення interactivePopGestureRecognizer.delegate = nilмає небажані побічні ефекти.

Налаштування navigationController?.navigationBar.hidden = trueпрацює, але не дозволяє приховувати зміни в панелі навігації.

Нарешті, зазвичай є кращою практикою створювати об’єкт моделі, який є UIGestureRecognizerDelegateдля вашого навігаційного контролера. Причиною помилок UINavigationControllerє встановлення його на контролер у стеку EXC_BAD_ACCESS.

Повне рішення

Спочатку додайте цей клас до свого проекту:

class InteractivePopRecognizer: NSObject, UIGestureRecognizerDelegate {

    var navigationController: UINavigationController

    init(controller: UINavigationController) {
        self.navigationController = controller
    }

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return navigationController.viewControllers.count > 1
    }

    // This is necessary because without it, subviews of your top controller can
    // cancel out your gesture recognizer on the edge.
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

Потім встановіть навігаційні контролери interactivePopGestureRecognizer.delegateна екземпляр нового InteractivePopRecognizerкласу.

var popRecognizer: InteractivePopRecognizer?

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

private func setInteractiveRecognizer() {
    guard let controller = navigationController else { return }
    popRecognizer = InteractivePopRecognizer(controller: controller)
    controller.interactivePopGestureRecognizer?.delegate = popRecognizer
}

Насолоджуйтесь прихованою панеллю навігації без побічних ефектів, яка працює, навіть якщо ваш верхній контролер має підпрогляди таблиць, колекцій або прокрутки.


1
Чудове рішення!
Matt Butler

1
Найкраща відповідь, дякую!
Дорі Даніель

2
@HunterMaximillionMonk дякую за чудове рішення. Це працює як шарм
як diu

1
@HunterMaximillionMonk це, здається, працює правильно, але проблема з цим, коли у мене є кілька контролерів, після чого через один раз він перестає працювати.
Премал Хетані,

1
Безумовно, найкраща відповідь!
daxh

54

У моєму випадку для запобігання дивних наслідків

Кореневий контролер подання

override func viewDidLoad() {
    super.viewDidLoad()

    // Enable swipe back when no navigation bar
    navigationController?.interactivePopGestureRecognizer?.delegate = self 

}


func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if(navigationController!.viewControllers.count > 1){
        return true
    }
    return false
}

http://www.gampood.com/pop-viewcontroller-with-out-navigation-bar/


2
Іноді я отримую EXC_BAD_ACCESS, коли використовую це
Андрій Гордєєв

Для мене це не змушує жест працювати і часто падає зEXEC_BAD_ACCESS
Бенджоном

2
Не забудьте додати UIGestureRecognizerDelegateдо кореневого контролера подання ... У моєму випадку делегатові було встановлено нуль у пізнішому контролері подання, ніж контролер кореневого перегляду, тому при поверненні до кореневого контролера подання gestureRecognizerShouldBeginне викликався. Таким чином , я помістив .delegate = selfв viewDidAppear(). Це вирішило дивні ефекти в моєму випадку .. Вітаємо!
Wiingaard,

@AndreyGordeev Не могли б ви дати деякі подробиці про те, коли EXEC_BAD_ACCESSце відбувається?
Jaybo

Ось додаткова інформація про EXC_BAD_ACCESSпомилку: stackoverflow.com/questions/28746123/…
Андрій Гордєєв

25

Оновлено для iOS 13.4

iOS 13.4 зламав попереднє рішення, тому все стане неприємним. Схоже, в iOS 13.4 ця поведінка тепер контролюється приватним методом _gestureRecognizer:shouldReceiveEvent:(не плутати з новим загальнодоступним shouldReceiveметодом, доданим в iOS 13.4).


Я виявив, що інші опубліковані рішення, які перевизначають делегата, або встановлення його на нуль спричинили несподівану поведінку.

У моєму випадку, коли я знаходився на вершині стека навігації і намагався використати жест, щоб вивести ще один, він зазнав би невдачі (як і передбачалося), але подальші спроби натиснення на стек почали б викликати дивні графічні збої в панель навігації. Це має сенс, оскільки делегат використовується не лише для того, щоб заблокувати розпізнавання жесту, коли навігаційна панель прихована, і вся ця інша поведінка була викинута.

З мого тестування виявляється, що gestureRecognizer(_:, shouldReceiveTouch:)саме цей метод реалізує оригінальний делегат, щоб заблокувати розпізнавання жесту, коли навігаційна панель прихована, а не gestureRecognizerShouldBegin(_:). Інші рішення, які реалізовуються gestureRecognizerShouldBegin(_:)у своїх делегатських роботах, оскільки відсутність реалізації gestureRecognizer(_:, shouldReceiveTouch:)призведе до поведінки за замовчуванням при отриманні всіх дотиків.

Рішення @Nathan Perry наближається, але без реалізації respondsToSelector(_:)коду UIKit, який надсилає повідомлення делегатові, буде вважати, що немає реалізації для будь-якого іншого методу делегування, і forwardingTargetForSelector(_:)ніколи не отримає виклику.

Отже, ми беремо під контроль `gestureRecognizer (_ :, shouldReceiveTouch :) в одному конкретному сценарії, в якому ми хочемо змінити поведінку, і в іншому випадку пересилаємо все інше до делегата.

class AlwaysPoppableNavigationController : UINavigationController {

    private var alwaysPoppableDelegate: AlwaysPoppableDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.alwaysPoppableDelegate = AlwaysPoppableDelegate(navigationController: self, originalDelegate: self.interactivePopGestureRecognizer!.delegate!)
        self.interactivePopGestureRecognizer!.delegate = self.alwaysPoppableDelegate
    }
}

private class AlwaysPoppableDelegate : NSObject, UIGestureRecognizerDelegate {

    weak var navigationController: AlwaysPoppableNavigationController?
    weak var originalDelegate: UIGestureRecognizerDelegate?

    init(navigationController: AlwaysPoppableNavigationController, originalDelegate: UIGestureRecognizerDelegate) {
        self.navigationController = navigationController
        self.originalDelegate = originalDelegate
    }

    // For handling iOS before 13.4
    @objc func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if let navigationController = navigationController, navigationController.isNavigationBarHidden && navigationController.viewControllers.count > 1 {
            return true
        }
        else if let originalDelegate = originalDelegate {
            return originalDelegate.gestureRecognizer!(gestureRecognizer, shouldReceive: touch)
        }
        else {
            return false
        }
    }

    // For handling iOS 13.4+
    @objc func _gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceiveEvent event: UIEvent) -> Bool {
        if let navigationController = navigationController, navigationController.isNavigationBarHidden && navigationController.viewControllers.count > 1 {
            return true
        }
        else if let originalDelegate = originalDelegate {
            let selector = #selector(_gestureRecognizer(_:shouldReceiveEvent:))
            if originalDelegate.responds(to: selector) {
                let result = originalDelegate.perform(selector, with: gestureRecognizer, with: event)
                return result != nil
            }
        }

        return false
    }

    override func responds(to aSelector: Selector) -> Bool {
        if #available(iOS 13.4, *) {
            // iOS 13.4+ does not need to override responds(to:) behavior, it only uses forwardingTarget
            return originalDelegate?.responds(to: aSelector) ?? false
        }
        else {
            if aSelector == #selector(gestureRecognizer(_:shouldReceive:)) {
                return true
            }
            else {
                return originalDelegate?.responds(to: aSelector) ?? false
            }
        }
    }

    override func forwardingTarget(for aSelector: Selector) -> Any? {
        if #available(iOS 13.4, *), aSelector == #selector(_gestureRecognizer(_:shouldReceiveEvent:)) {
            return nil
        }
        else {
            return self.originalDelegate
        }
    }
}

1
Схоже, ваше рішення є найкращим на даний момент. Дякую!
Тимур Бернікович

"але подальші спроби натиснути на стек почали б викликати дивні графічні збої в панелі навігації" - я тут збентежений. Я думав, у нас немає навігаційної панелі? Це питання? У моїй ситуації у мене є контролер навігації, вбудований як контролер дочірнього перегляду без панелі навігації; VC, що містить, має елементи керування навігацією. Отже, я дозволив вміщуючий ВК бути делегатом розпізнавача і щойно зробив gestureRecognizerShouldBegin:це, і це, здається, спрацьовує. Цікаво, чи варто мені пильнувати?
skagedal 02

2
Це спричинило витік пам’яті, оскільки це navigationControllerбуло надійним посиланням у AlwaysPoppableDelegate. Я відредагував код, щоб зробити це weakпосиланням.
Грем Перкс,

3
Це приємне рішення вже не працює в iOS 13.4
Елі,

@ChrisVasselli Дійсно чудово, дякую! Сподіваємось, це пройде перевірку приватних методів огляду App Store.
Елі,

16

Ви можете підклас UINavigationController наступним чином:

@interface CustomNavigationController : UINavigationController<UIGestureRecognizerDelegate>

@end

Реалізація:

@implementation CustomNavigationController

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated {
    [super setNavigationBarHidden:hidden animated:animated];
    self.interactivePopGestureRecognizer.delegate = self;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.viewControllers.count > 1) {
        return YES;
    }
    return NO;
}

@end

2
Використання цього підходу - це розбиття поп-жесту при UIPageViewControllerпрокрутці.
атулхатрі

Я виявив, що viewController.count> 1 перевірка необхідна. Якщо користувач намагається провести пальцем назад лише за допомогою кореневого VC, інтерфейс буде зависати при наступному натисканні VC.
VaporwareWolf

11

Проста, без побічних ефектів відповідь

Хоча більшість відповідей тут хороші, вони, мабуть, мають ненавмисні побічні ефекти (розбиття додатків) або є багатослівними.

Найпростішим, але функціональним рішенням, яке я міг придумати, було наступне:

У ViewController, що ви приховуєте панель навігації,

class MyNoNavBarViewController: UIViewController {
    
    // needed for reference when leaving this view controller
    var initialInteractivePopGestureRecognizerDelegate: UIGestureRecognizerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // we will need a reference to the initial delegate so that when we push or pop.. 
        // ..this view controller we can appropriately assign back the original delegate
        initialInteractivePopGestureRecognizerDelegate = self.navigationController?.interactivePopGestureRecognizer?.delegate
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        // we must set the delegate to nil whether we are popping or pushing to..
        // ..this view controller, thus we set it in viewWillAppear()
        self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
    }

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

        // and every time we leave this view controller we must set the delegate back..
        // ..to what it was originally
        self.navigationController?.interactivePopGestureRecognizer?.delegate = initialInteractivePopGestureRecognizerDelegate
    }
}

Інші відповіді пропонують просто встановити делегата на нуль. Проведення пальцем назад до початкового контролера перегляду в навігаційному стеку призводить до відключення всіх жестів. Можливо, якийсь нагляд за розробниками UIKit / UIGesture.

Крім того, деякі відповіді тут, які я реалізував, призвели до нестандартної поведінки навігації Apple (зокрема, дозволяючи можливість прокручувати вгору або вниз, а також проводячи назад). Ці відповіді також здаються дещо багатослівними, а в деяких випадках неповними.


viewDidLoad()не є вдалим місцем для захоплення, initialInteractivePopGestureRecognizerDelegateоскільки там navigationControllerможе бути нуль (ще не натиснуто на стек). viewWillAppearмісця, де ви ховаєте панель навігації, було б більш доречним
nCod3d,

10

Спираючись на відповідь Hunter Maximillion Monk , я зробив підклас для UINavigationController, а потім встановив власний клас для мого UINavigationController у моїй розкадровці. Остаточний код для двох класів виглядає так:

InteractivePopRecognizer:

class InteractivePopRecognizer: NSObject {

    // MARK: - Properties

    fileprivate weak var navigationController: UINavigationController?

    // MARK: - Init

    init(controller: UINavigationController) {
        self.navigationController = controller

        super.init()

        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }
}

extension InteractivePopRecognizer: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return (navigationController?.viewControllers.count ?? 0) > 1
    }

    // This is necessary because without it, subviews of your top controller can cancel out your gesture recognizer on the edge.
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

HiddenNavBarNavigationController:

class HiddenNavBarNavigationController: UINavigationController {

    // MARK: - Properties

    private var popRecognizer: InteractivePopRecognizer?

    // MARK: - Lifecycle

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

    // MARK: - Setup

    private func setupPopRecognizer() {
        popRecognizer = InteractivePopRecognizer(controller: self)
    }
}

Розкадровка:

Користувальницький клас навігатора раскадровки


8

Схоже, рішення, надане @ChrisVasseli, є найкращим. Я хотів би надати таке саме рішення в Objective-C, оскільки питання стосується Objective-C (див. Теги)

@interface InteractivePopGestureDelegate : NSObject <UIGestureRecognizerDelegate>

@property (nonatomic, weak) UINavigationController *navigationController;
@property (nonatomic, weak) id<UIGestureRecognizerDelegate> originalDelegate;

@end

@implementation InteractivePopGestureDelegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if (self.navigationController.navigationBarHidden && self.navigationController.viewControllers.count > 1) {
        return YES;
    } else {
        return [self.originalDelegate gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
    }
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
    if (aSelector == @selector(gestureRecognizer:shouldReceiveTouch:)) {
        return YES;
    } else {
        return [self.originalDelegate respondsToSelector:aSelector];
    }
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    return self.originalDelegate;
}

@end

@interface NavigationController ()

@property (nonatomic) InteractivePopGestureDelegate *interactivePopGestureDelegate;

@end

@implementation NavigationController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.interactivePopGestureDelegate = [InteractivePopGestureDelegate new];
    self.interactivePopGestureDelegate.navigationController = self;
    self.interactivePopGestureDelegate.originalDelegate = self.interactivePopGestureRecognizer.delegate;
    self.interactivePopGestureRecognizer.delegate = self.interactivePopGestureDelegate;
}

@end

3
Тому що ObjC ще не вмер! 😉
MonsieurDart

2
Це правильне рішення. Будь-яке інше рішення, яке не пересилається оригінальному представнику, є неправильним.
Джош Бернфельд,

6

Моє рішення полягає в безпосередньому розширенні UINavigationControllerкласу:

import UIKit

extension UINavigationController: UIGestureRecognizerDelegate {

    override open func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        self.interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return self.viewControllers.count > 1
    }

}

Таким чином, всі контролери навігації можна буде відхилити, розсунувши.


Як не дивно, це спричиняє viewDidAppearігнорування всіх дзвінків на VC, що належать будь-якому навігаційному контролеру.
cumanzor

4

Ви можете зробити це за допомогою делегата проксі. Створюючи контролер навігації, захопіть наявного делегата. І передайте його в проксі. Потім передайте всі методи делегування існуючому делегатові, крім gestureRecognizer:shouldReceiveTouch:використанняforwardingTargetForSelector:

Налаштування:

let vc = UIViewController(nibName: nil, bundle: nil)
let navVC = UINavigationController(rootViewController: vc)
let bridgingDelegate = ProxyDelegate()
bridgingDelegate.existingDelegate = navVC.interactivePopGestureRecognizer?.delegate
navVC.interactivePopGestureRecognizer?.delegate = bridgingDelegate

Делегат проксі:

class ProxyDelegate: NSObject, UIGestureRecognizerDelegate {
    var existingDelegate: UIGestureRecognizerDelegate? = nil

    override func forwardingTargetForSelector(aSelector: Selector) -> AnyObject? {
        return existingDelegate
    }

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        return true
    }  
}

Ця відповідь справжня в стилі Obj-C!
Sound Blaster

forwardingTargetForSelector заощадив би мені стільки часу на минулому проекті, якби я про це знав. Хороший матеріал!
VaporwareWolf

4

Відповідь Hunter Monk дійсно приголомшлива, але, на жаль, в iOS 13.3.1 вона не працює.

Поясню ще один спосіб приховатись UINavigationBarі не загубити swipe to back gesture. Я тестував на iOS 13.3.1 та 12.4.3, і це працює.

Вам потрібно створити власний клас UINavigationControllerі встановити цей клас для UINavigationControllerвStoryboard

Встановіть для власного класу значення <code> UINavigationController </code>

НЕ приховуйте NavigationBarнаStoryboard

<code> UINavigationController </code> Інспектор атрибутів:

Приклад Storyboard:

Розкадровка:

І нарешті, помістіть це: navigationBar.isHidden = trueв viewDidLoadзCustomNavigationController класу.

Переконайтеся, що НЕ використовуйте цей метод setNavigationBarHidden(true, animated: true)для приховування файлу NavigationBar.

import UIKit

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationBar.isHidden = true
    }
}

2
Я перевірив це на реальному пристрої iPhone 6S Plus, iOS 13.4.1і проведіть пальцем назад.
Емре Айдін,

1
працює також на найновішій версії iOS 14.0.1
bezoadam

1

Ксамарін Відповідь:

Реалізуйте IUIGestureRecognizerDelegateінтерфейс у визначенні класу ViewController:

public partial class myViewController : UIViewController, IUIGestureRecognizerDelegate

У своєму ViewController додайте такий спосіб:

[Export("gestureRecognizerShouldBegin:")]
public bool ShouldBegin(UIGestureRecognizer recognizer) {
  if (recognizer is UIScreenEdgePanGestureRecognizer && 
      NavigationController.ViewControllers.Length == 1) {
    return false;
  }
  return true;
}

У своєму ViewController ViewDidLoad()додайте такий рядок:

NavigationController.InteractivePopGestureRecognizer.Delegate = this;

Імовірно, це є в UINavigationControllerконтролері кореневого перегляду? Я отримую, EXEC_BAD_ACCESSколи я спробую це.
Benjohn

Ви можете зробити панорамування краю на контролері кореневого перегляду? Це не повинно бути можливим, тому що коли ви знаходитесь у кореневому ВК, ви вискакуєте всі інші ВК, а довжина масиву ВК вашого Nav повинна бути 1.
Ахмад,

Збій відбувається перед викликом gestureRecognizerShouldBegin:.
Бенджон,

1
Чи можете ви розмістити свій код ВК в новому запитанні або на форумах Xamarin?
Ахмад,

Ні, я ні. Думаю, залишу це на .1!
Benjohn

1

Я спробував це, і воно працює чудово: як приховати панель навігації, не втрачаючи можливості повернення назад

Ідея полягає в тому, щоб реалізувати "UIGestureRecognizerDelegate" у своєму .h та додати це у свій .m-файл.

- (void)viewWillAppear:(BOOL)animated {
// hide nav bar
[[self navigationController] setNavigationBarHidden:YES animated:YES];

// enable slide-back
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
  }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
   return YES;  
}

1

Ось моє рішення: я міняю альфу на панелі навігації, але панель навігації не прихована. Всі мої контролери подання є підкласом мого BaseViewController, і там я маю:

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    navigationController?.navigationBar.alpha = 0.0
}

Ви також можете підклас UINavigationController і помістити цей метод туди.


0

Деякі люди досягли успіху, викликавши setNavigationBarHiddenметод із анімованим YES.


Я не пробував удачі. Оновлення моєї відповіді для висвітлення цієї пропозиції.
mihai

0

На моєму перегляді контролер без навігаційної панелі я використовую

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

  CATransaction.begin()
  UIView.animate(withDuration: 0.25, animations: { [weak self] in
    self?.navigationController?.navigationBar.alpha = 0.01
  })
  CATransaction.commit()
}

open override func viewWillDisappear(_ animated: Bool) {
  super.viewWillDisappear(animated)
  CATransaction.begin()
  UIView.animate(withDuration: 0.25, animations: { [weak self] in
    self?.navigationController?.navigationBar.alpha = 1.0
  })
  CATransaction.commit()
}

Під час інтерактивного звільнення кнопка "Назад" все-таки засвітиться, саме тому я її приховав.


-2

Існує дуже просте рішення, яке я спробував і працює чудово, воно є в Xamarin.iOS, але його можна застосувати і до рідної:

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        this.NavigationController.SetNavigationBarHidden(true, true);
    }

    public override void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);
        this.NavigationController.SetNavigationBarHidden(false, false);
        this.NavigationController.NavigationBar.Hidden = true;
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);
        this.NavigationController.SetNavigationBarHidden(true, false);
    }

-6

Ось як вимкнути розпізнавач жестів, коли користувач вислизає з ViewController. Ви можете вставити його у ваші viewWillAppear () або у ваші методи ViewDidLoad ().

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

Будь ласка, прочитайте питання перед тим, як розміщувати відповіді. Питання полягало в тому, щоб увімкнути його, а не вимкнути. МИ ЛЮБИМО ПОП-ЖЕСТ.
Йогеш Махешварі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.