Изменить направление InteractivePopGestureRecognizer

Мое приложение поддерживает английский и арабский языки. interactivePopGestureRecognizer работает правильно при использовании английского языка, т. е. при смахивании слева направо, он выскакивает viewController. Но когда я использую арабский, я изменил semanticContentAttribute справа налево.

if([[[NSUserDefaults standardUserDefaults] objectForKey:@"LanguageCode"] isEqualToString:@"en"])
    {
        [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];       //View for English language
    }
    else
    {
        [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceRightToLeft];       //mirror view for Arabic language
    }

Но interactivePopGestureRecogniser по-прежнему слева направо. Как я могу изменить направление interactivePopGestureRecogniser такой, что поддерживает арабский? Я хочу провести пальцем справа налево для всплывающего окна просмотра контроллера на арабском языке.

1 ответ

Я нашел решение для этого после долгих поисков, если кто-то ищет.

Предыдущий ответ может привести к зависанию / зависанию пользовательского интерфейса.

Причина, по которой пользовательский интерфейс зависает / зависает, заключается в том, что UINavigationController отсутствует проверка для контроллера корневого представления, когда жест выполняется в корневом представлении. Есть несколько способов исправить это, вот что я сделал.

Вы должны создать подкласс UINavigationController, это правильный путь и добавить реализацию следующим образом:

class RTLNavController: UINavigationController, UINavigationControllerDelegate, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //  Adding swipe to pop viewController
        self.interactivePopGestureRecognizer?.isEnabled = true
        self.interactivePopGestureRecognizer?.delegate = self

        //  UINavigationControllerDelegate
        self.delegate = self
    }
    
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        navigationController.view.semanticContentAttribute = UIView.isRightToLeft() ? .forceRightToLeft : .forceLeftToRight
        navigationController.navigationBar.semanticContentAttribute = UIView.isRightToLeft() ? .forceRightToLeft : .forceLeftToRight
    }

    //  Checking if the viewController is last, if not disable the gesture
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if self.viewControllers.count > 1 {
            return true
        }
        
        return false
    }
}

extension UIView {
    static func isRightToLeft() -> Bool {
        return UIView.appearance().semanticContentAttribute == .forceRightToLeft
    }
}

Ресурсы:

Исходный вопрос:

Ответ используется для решения:

Другое решение, которое может работать лучше (но оно в Objective-C):

После многих испытаний у меня сработало единственное решение:

Свифт 3:

extension UIViewController {
    open override func awakeFromNib() {
        super.awakeFromNib()
        navigationController?.view.semanticContentAttribute = .forceRightToLeft
        navigationController?.navigationBar.semanticContentAttribute = .forceRightToLeft
    }
}

Вы можете исключить семантический атрибут для определенных типов, таких как:

UIView.appearance(whenContainedInInstancesOf: [UITableViewCell.self]).semanticContentAttribute = .forceLeftToRight
Другие вопросы по тегам