UINavigationController'da Gezinme Çubuğunu gizlerken Geri Kaydırma yok


86

Görünümlerinizi bir UINavigationController. Maalesef bunu gizlemenin bir yolunu bulamıyorum NavigationBarama yine de dokunmatik pan kaydırmayı geri çekiyorum gesture. Özel hareketler yazabilirim ancak bunun yerine UINavigationControllergeri kaydırmayı tercih etmem ve buna güvenmeyi tercih ederim gesture.

Film şeridinde işaretini kaldırırsam, geri kaydırma çalışmıyor

görüntü açıklamasını buraya girin

alternatif olarak programlı olarak gizlersem, aynı senaryo.

Üstü gizleyip NavigationBarkaydırmaya devam etmenin bir yolu yok mu?


1
UIGestureRecognizer eklemek kabul edilebilir mi? Uygulaması çok kolay.
SwiftArchitect

1
@LancelotdelaMare, UINavigationController'ın geri kaydırması kadar sorunsuz çalışmayacağı için bundan kaçınmaya çalışıyordum. UIScreenEdgePanGestureRecognizer'a bakıyorum, çünkü bazıları yardımcı olduğunu söylüyor, ancak henüz işe yaramadı. Burada en basit ve en zarif çözümü arıyorsunuz.
mihai

Yanıtlar:


98

Çalıştığını bir hack ayarlamaktır interactivePopGestureRecognizerarasında bireyin temsilci UINavigationControlleriçin nilböyle:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

Ancak bazı durumlarda garip etkiler yaratabilir.


16
"art arda geri kaydırmak, yığın üzerinde yalnızca bir görüntüleme denetleyicisi olduğunda hareketin tanınmasına neden olabilir ve bu da, bir UI'yi (UIKit mühendisleri tarafından beklenmedik bir şekilde) herhangi bir hareketi tanımayı durdurduğu bir duruma
getirir

4
Beklenmedik devlete karşı koruyabilir alternatif (benim app temsilci kullanılır) bazı düşük seviyeli nesnesine ayarlayın ve uygulamak olacaktır gestureRecognizerShouldBegindönen, trueeğer navigationController'ın viewControllersayımı is 0'dan büyük
Kenny Winker

4
Bu işe yarasa da buna karşı şiddetle tavsiye ediyorum. Temsilcinin kırılması, nadir görülen ve tanımlanması zor bir ana iş parçacığı bloğuna neden oluyordu. Bunun bir ana iş parçacığı bloğu değil, @HorseT tarafından tanımlandığı ortaya çıktı.
Josh Bernfeld

3
Uygulamam temsilci tutamacını kaydediyor, ardından geri yüklüyor viewWillDisappearve şu ana kadar herhangi bir olumsuz yan etki yaşamadı.
Don Park

1
!!!! Arda garip davranış oluştuğunda tokatlamak kullanırken Son derece bu çözümü kullanmak cesaretini, geri engelli ve bütün uygulama doens't yanıt herhangi fazlasıdır
KarimIhab

81

Diğer Yöntemlerle İlgili Sorunlar

Ayarlamanın interactivePopGestureRecognizer.delegate = nilistenmeyen yan etkileri vardır.

Ayar navigationController?.navigationBar.hidden = trueçalışıyor, ancak gezinme çubuğundaki değişikliğinizin gizlenmesine izin vermiyor.

Son olarak, UIGestureRecognizerDelegategezinme denetleyicinize uygun bir model nesne oluşturmak genellikle daha iyi bir uygulamadır . Bunu UINavigationControlleryığındaki bir denetleyiciye ayarlamak , EXC_BAD_ACCESShatalara neden olan şeydir .

Tam Çözüm

Öncelikle bu sınıfı projenize ekleyin:

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

Ardından, gezinme denetleyicinizi interactivePopGestureRecognizer.delegateyeni InteractivePopRecognizersınıfınızın bir örneğine ayarlayın .

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
}

Üst denetleyicinizde tablo, koleksiyon veya kaydırma görünümü alt görünümleri olsa bile çalışan, yan etkisi olmayan gizli bir gezinme çubuğunun keyfini çıkarın.


2
Harika çözüm!
Matt Butler

2
En iyi cevap, teşekkürler!
Dory Daniel

3
@HunterMaximillionMonk harika çözüm için teşekkürler. Bir cazibe gibi çalışıyor
diu gibi

2
Kesinlikle en iyi cevap!
daxh

2
İOS 13.5, 12.4.6 ve 10.3.4'te çalıştı. Teşekkürler.
Денис Попов

55

Benim durumumda, garip etkileri önlemek için

Kök görünüm denetleyicisi

override func viewDidLoad() {
    super.viewDidLoad()

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

// UIGestureRecognizerDelegate
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if let navVc = navigationController {
      return navVc.viewControllers.count > 1
    }
    return false
}

2
Bazen bunu kullanırken EXC_BAD_ACCESS alıyorum
Andrey Gordeev

Benim için, hareketi işe yaramıyor ve sık sıkEXEC_BAD_ACCESS
Benjohn

2
UIGestureRecognizerDelegateKök görünüm denetleyicisine eklemeyi unutmayın ... Benim durumumda, temsilci, kök görünüm denetleyicisinden daha sonraki bir görünüm denetleyicisinde nil olarak ayarlandı, bu nedenle kök görünüm denetleyicisine geri döndüğünde gestureRecognizerShouldBeginçağrılmadı. Bu yüzden yerleştirilir .delegate = selfiçinde viewDidAppear(). Bu benim durumumdaki garip etkileri çözdü .. Şerefe!
Wiingaard

@AndreyGordeev Ne zaman EXEC_BAD_ACCESSolacağı hakkında biraz bilgi verebilir misiniz ?
Jaybo

EXC_BAD_ACCESSHata hakkında daha fazla bilgi : stackoverflow.com/questions/28746123/…
Andrey Gordeev

25

İOS 13.4 için güncellendi

iOS 13.4 önceki çözümü bozdu, bu yüzden işler çirkinleşecek. Görünüşe göre iOS 13.4'te bu davranış artık özel bir yöntemle kontrol ediliyor _gestureRecognizer:shouldReceiveEvent:( shouldReceiveiOS 13.4'te eklenen yeni genel yöntemle karıştırılmamalıdır).


Temsilciyi geçersiz kılan veya sıfır olarak ayarlayan diğer yayınlanmış çözümlerin bazı beklenmedik davranışlara neden olduğunu buldum.

Benim durumumda, gezinme yığınının tepesindeyken ve hareketi bir tane daha patlatmak için kullanmaya çalıştığımda, başarısız olurdu (beklendiği gibi), ancak daha sonra yığına itme girişimleri, gezinti çubuğu. Bu mantıklıdır, çünkü temsilci, gezinme çubuğu gizlendiğinde hareketin tanınmasını engelleyip engellemekten daha fazlasını ele almak için kullanılıyor ve diğer tüm davranışlar atılıyordu.

Benim testlerime göre, gestureRecognizer(_:, shouldReceiveTouch:)orijinal temsilcinin hareketin gezinme çubuğu gizlendiğinde tanınmasını engellemek için uyguladığı yöntem olduğu anlaşılıyor gestureRecognizerShouldBegin(_:). gestureRecognizerShouldBegin(_:)Temsilci çalışmalarında uygulayan diğer çözümler, çünkü bir uygulamasının olmaması, gestureRecognizer(_:, shouldReceiveTouch:)tüm dokunuşları almanın varsayılan davranışına neden olacaktır.

@Nathan Perry'nin çözümü yaklaşıyor, ancak respondsToSelector(_:)temsilciye mesajlar gönderen UIKit kodu uygulaması olmadan , diğer delege yöntemlerinin hiçbiri için uygulama olmadığına inanacak ve forwardingTargetForSelector(_:)asla çağrılmayacaktır.

Bu nedenle, davranışı değiştirmek istediğimiz belirli bir senaryoda `jestRecognizer (_ :, shouldReceiveTouch :) kontrolünü ele alıyoruz ve diğer her şeyi temsilciye iletiyoruz.

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
Görünüşe göre çözümünüz şu an için en iyisi. Teşekkürler!
Timur Bernikovich

"ancak daha sonra yığına itme girişimleri gezinme çubuğunda tuhaf grafik hatalara neden olmaya başlayacaktır" - burada kafam karıştı. Gezinme çubuğumuz yok sanıyordum? Soru bu? Benim durumumda, navbar olmadan çocuk görünümü denetleyicisi olarak yerleştirilmiş bir gezinme denetleyicim var; içeren VC gezinme kontrollerine sahiptir. Bu yüzden, içerdiği VC'nin tanıyan delegesi olmasına izin verdim ve sadece gestureRecognizerShouldBegin:şeyi yaptım ve "işe yarıyor gibi görünüyor". Bakmalı mıyım merak ediyorum.
skagedal

2
navigationControllerAlwaysPoppableDelegate'de güçlü bir referans olduğu için bu bellek sızıntısı yaşadı. Bunu bir weakreferans yapmak için kodu düzenledim .
Graham Perks

3
Bu güzel çözüm iOS 13.4'te artık çalışmıyor
Ely

@ChrisVasselli Gerçekten harika, teşekkürler! Umarım bu, App Store incelemesinin özel yöntem kontrolünden geçecektir.
Ely

16

UINavigationController'ı aşağıdaki gibi alt sınıflandırabilirsiniz:

@interface CustomNavigationController : UINavigationController<UIGestureRecognizerDelegate>

@end

Uygulama:

@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
Bu yaklaşımı kullanmak, fazla UIPageViewControllerkaydırmada pop hareketini bozuyor.
atulkhatri

ViewController.count> 1 kontrolünün gerekli olduğunu buldum. Kullanıcı yalnızca kök VC ile geri kaydırmaya çalışırsa, UI bir sonraki VC itişinde askıda kalır.
VaporwareWolf

12

Basit, yan etki yok Cevap

Buradaki yanıtların çoğu iyi olsa da, görünüşte istenmeyen yan etkileri var (uygulama kırma) veya ayrıntılı.

Bulabildiğim en basit ama işlevsel çözüm şuydu:

NavigationBar'ı gizlediğiniz ViewController'da,

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

Diğer yanıtlar, yalnızca temsilcinin sıfır olarak ayarlanmasını önerdi. Gezinme yığınındaki ilk görünüm denetleyicisine geriye doğru kaydırmak, tüm hareketlerin devre dışı bırakılmasına neden olur. Belki de UIKit / UIGesture geliştiricilerinin bir tür gözetimi.

Ayrıca, burada uyguladığım bazı cevaplar standart olmayan elma gezinme davranışıyla sonuçlandı (özellikle, yukarı veya aşağı kaydırırken aynı zamanda geriye doğru kaydırma yeteneğine izin veriyor). Bu cevaplar da biraz ayrıntılı ve bazı durumlarda eksik görünüyor.


viewDidLoad()yakalamak için bir yer değil initialInteractivePopGestureRecognizerDelegateçünkü navigationController(henüz yığını üzerine itilir olmayan) sıfır olabilir. viewWillAppearGezinme çubuğunu sakladığınız yer daha uygun olacaktır
nCod3d

10

Off Bina Hunter Maximillion Monk'un cevap , ben UINavigationController için bir alt sınıfı ve beni Film şeridinde benim UINavigationController için özel sınıf ayarlayın. İki sınıf için nihai kod şuna benzer:

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

Storyboard:

Storyboard nav denetleyicisi özel sınıfı


8

@ChrisVasseli tarafından sağlanan çözüm en iyisi gibi görünüyor. Aynı çözümü Objective-C'de sunmak istiyorum çünkü soru Objective-C ile ilgili (etiketlere bakın)

@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
Çünkü ObjC henüz ölmedi! 😉
MonsieurDart

2
Doğru çözüm budur. Orijinal temsilciye iletmeyen diğer herhangi bir çözüm yanlıştır.
Josh Bernfeld

6

Benim çözümüm UINavigationControllersınıfı doğrudan genişletmek :

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
    }

}

Bu şekilde, tüm gezinme denetleyicileri kaydırılarak kapatılabilir.


İşin garibi, bu, viewDidAppearherhangi bir gezinme denetleyicisine ait VC'lerdeki tüm çağrıların göz ardı edilmesine neden oluyor .
cumanzor

4

Bir Vekil Temsilcisi ile yapabilirsiniz. Gezinti denetleyicisini oluştururken mevcut temsilciyi alın. Ve vekile iletin. Ardından, tüm temsilci yöntemlerini mevcut temsilciye iletin.gestureRecognizer:shouldReceiveTouch: kullanmakforwardingTargetForSelector:

Kurmak:

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

Proxy Temsilcisi:

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

Bu cevap gerçek Obj-C tarzıdır!
Sound Blaster

forwardingTargetForSelector, geçmiş bir projede bilseydim bana çok zaman kazandırırdı. İyi şeyler!
VaporwareWolf

4

Hunter Monk'un cevabı gerçekten harika, ancak ne yazık ki iOS 13.3.1'de çalışmıyor.

Saklanmanın UINavigationBarve kaybetmemenin başka bir yolunu açıklayacağım swipe to back gesture. İOS 13.3.1 ve 12.4.3'te test ettim ve çalışıyor.

Özel bir sınıf oluşturmanız UINavigationControllerve bu sınıfı in için ayarlamanız gerekir UINavigationController.Storyboard

Özel sınıfı <code> UINavigationController </code> olarak ayarlayın

NavigationBarÜzerinde GİZLEMEYİNStoryboard

<code> UINavigationController </code> Öznitelik denetçisi:

Örnek Storyboard:

Storyboard:

Ve son olarak şunu koyun: navigationBar.isHidden = truein viewDidLoadofCustomNavigationController sınıfın.

, Emin olun bu yöntemi KULLANMAYIN setNavigationBarHidden(true, animated: true)gizlemek için NavigationBar.

import UIKit

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationBar.isHidden = true
    }
}

2
Bunu gerçek cihaz iPhone 6S Plus ile test ettim iOS 13.4.1ve geri kaydırın çalışır.
Emre Aydın

1

Xamarin Cevabı:

Uygulamak IUIGestureRecognizerDelegateiçin viewController en Sınıf tanımında Arayüzü:

public partial class myViewController : UIViewController, IUIGestureRecognizerDelegate

ViewController'ınızda aşağıdaki yöntemi ekleyin:

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

ViewController ViewDidLoad()cihazınızda aşağıdaki satırı ekleyin:

NavigationController.InteractivePopGestureRecognizer.Delegate = this;

Muhtemelen bu, UINavigationControllerkök görünüm denetleyicisinde mi? Bunu EXEC_BAD_ACCESSdenediğimde anlıyorum.
Benjohn

Kök görünüm denetleyicisinde yatay kaydırmayı yapabiliyor musunuz? Bu mümkün olmamalı çünkü kök VC'deyken diğer tüm VC'leri patlatmışsınızdır ve Nav'unuzun VC dizisinin uzunluğu 1 olmalıdır.
Ahmad

Çökme, çağrı yapılmadan önce gerçekleşir gestureRecognizerShouldBegin:.
Benjohn

1
VC kodunuzu yeni bir Soruya veya Xamarin forumlarına gönderebilir misiniz?
Ahmad

Hayır, yapmadım. Sanırım .1 için bırakacağım!
Benjohn

1

Bunu denedim ve mükemmel çalışıyor: Geri kayma özelliğini kaybetmeden Gezinme Çubuğu nasıl gizlenir

Buradaki fikir, .h dosyanıza "UIGestureRecognizerDelegate" uygulamak ve bunu .m dosyanıza eklemektir.

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

İşte benim çözümüm: Gezinme çubuğunda alfa değiştiriyorum, ancak gezinme çubuğu gizli değil. Tüm görünüm denetleyicilerim, BaseViewController'imin bir alt sınıfıdır ve burada:

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

Ayrıca UINavigationController'ı alt sınıflayabilir ve bu yöntemi oraya koyabilirsiniz.


0

Bazı insanlarsetNavigationBarHidden yöntemi animasyonlu olarak çağırarak başarılı YESoldular.


Şansı denemedim. Cevabım bu öneriyi kapsayacak şekilde güncelleniyor.
mihai

0

Gezinme çubuğu olmayan görünüm denetleyicimde kullanıyorum

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

Etkileşimli işten çıkarma sırasında geri düğmesi parlayacak, bu yüzden onu sakladım.


-2

Denediğim ve mükemmel çalıştığım gerçekten basit bir çözüm var, bu Xamarin.iOS'ta ancak yerelde de uygulanabilir:

    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

Kullanıcı ViewController'den kayarak çıktığında hareket tanıyıcıyı nasıl devre dışı bırakacağınız aşağıda açıklanmıştır. Bunu, viewWillAppear () veya ViewDidLoad () yöntemlerinize yapıştırabilirsiniz.

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

Lütfen cevapları göndermeden önce soruyu okuyun. Soru, onu devre dışı bırakmak değil, etkinleştirmekle ilgiliydi. POP HAREKETİNİ SEVİYORUZ.
Yogesh Maheshwari
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.