Я поместил представление на контроллер навигации, и когда я нажимаю кнопку «Назад», он автоматически переходит к предыдущему представлению. Я хочу сделать несколько вещей при нажатии кнопки «Назад» перед тем, как вывести представление из стека. Что такое функция обратного вызова кнопки "Назад"?
102
Ответы:
Уильям Джокуши в ответ решить эту проблему с помощью простого трюка.
источник
На мой взгляд лучшее решение.
Но работает только с iOS5 +
источник
вероятно, лучше переопределить обратную кнопку, чтобы вы могли обработать событие до того, как появится представление для таких вещей, как подтверждение пользователя.
в viewDidLoad создайте UIBarButtonItem и установите для него self.navigationItem.leftBarButtonItem, передавая sel
Затем вы можете сделать такие вещи, как поднять UIAlertView для подтверждения действия, затем открыть контроллер представления и т. Д.
Или вместо создания новой кнопки возврата вы можете соответствовать методам делегата UINavigationController для выполнения действий при нажатии кнопки возврата.
источник
UINavigationControllerDelegate
него нет методов, которые вызываются при нажатии кнопки возврата.Это правильный способ обнаружить это.
этот метод вызывается также при отправке представления. Таким образом, проверка parent == nil предназначена для извлечения контроллера представления из стека
источник
Я получаю эти решения. Когда мы нажимаем кнопку возврата, вызывается метод viewDidDisappear. мы можем проверить, вызвав селектор isMovingFromParentViewController, который возвращает true. мы можем передать данные обратно (используя делегата). надеюсь, что это кому-то поможет.
источник
[super viewDidDisappear:animated]
Может быть, уже слишком поздно, но я и раньше хотел такого же поведения. И решение, которое я выбрал, довольно хорошо работает в одном из приложений, которые сейчас есть в App Store. Поскольку я не видел, чтобы кто-то использовал подобный метод, я хотел бы поделиться им здесь. Обратной стороной этого решения является необходимость создания подклассов
UINavigationController
. Хотя с помощью метода Swizzling могло бы помочь избежать этого, я не пошел так далеко.Итак, кнопка возврата по умолчанию фактически управляется
UINavigationBar
. Когда пользователь нажимает кнопку «Назад»,UINavigationBar
спросите своего делегата, следует ли открывать верхнюю частьUINavigationItem
, позвонивnavigationBar(_:shouldPop:)
.UINavigationController
на самом деле реализует это, но публично не заявляет, что принимаетUINavigationBarDelegate
(почему !?). Чтобы перехватить это событие, создайте подклассUINavigationController
, объявите его соответствиеUINavigationBarDelegate
и реализуйтеnavigationBar(_:shouldPop:)
. Вернитесь,true
если должен выскочить верхний предмет. Вернись,false
если останется.Есть две проблемы. Во-первых, вы должны вызвать
UINavigationController
версиюnavigationBar(_:shouldPop:)
в какой-то момент . НоUINavigationBarController
публично не заявляет о соответствииUINavigationBarDelegate
, попытка вызвать это приведет к ошибке времени компиляции. Решение, которое я выбрал, - использовать среду выполнения Objective-C, чтобы напрямую получить реализацию и вызвать ее. Пожалуйста, дайте мне знать, есть ли у кого-нибудь лучшее решение.Другая проблема заключается в том, что
navigationBar(_:shouldPop:)
сначала вызывается,popViewController(animated:)
если пользователь нажимает кнопку «Назад». Порядок меняется на противоположный, если контроллер представления выталкивается вызовомpopViewController(animated:)
. В этом случае я использую логическое значение, чтобы определить,popViewController(animated:)
вызывается раньше,navigationBar(_:shouldPop:)
что означает, что пользователь нажал кнопку возврата.Кроме того, я делаю расширение,
UIViewController
чтобы позволить контроллеру навигации запрашивать контроллер представления, следует ли его выскакивать, если пользователь нажимает кнопку «Назад». Контроллеры просмотра могут вернутьсяfalse
и выполнить любые необходимые действия, а также позвонитьpopViewController(animated:)
позже.А в вашем представлении контроллеры реализовывать
shouldBePopped(_:)
. Если вы не реализуете этот метод, по умолчанию контроллер представления будет появляться, как только пользователь нажмет кнопку «Назад», как обычно.Вы можете посмотреть мою демонстрацию здесь .
источник
Для "ПЕРЕД извлечением представления из стека":
источник
Есть более подходящий способ, чем спросить у viewControllers. Вы можете сделать свой контроллер делегатом навигационной панели, у которой есть кнопка возврата. Вот вам пример. В реализации контроллера, в котором вы хотите обрабатывать нажатие кнопки возврата, сообщите ему, что он будет реализовывать протокол UINavigationBarDelegate:
Затем где-нибудь в вашем коде инициализации (возможно, в viewDidLoad) сделайте ваш контроллер делегатом его панели навигации:
Наконец, реализуйте метод shouldPopItem. Этот метод вызывается сразу после нажатия кнопки возврата. Если у вас есть несколько контроллеров или элементов навигации в стеке, вы, вероятно, захотите проверить, какие из этих элементов навигации появляются (параметр элемента), чтобы вы могли выполнять свои собственные действия только тогда, когда вы этого ожидаете. Вот пример:
источник
Если вы не можете использовать «viewWillDisappear» или аналогичный метод, попробуйте создать подкласс UINavigationController. Это класс заголовка:
Класс реализации:
С другой стороны, вам нужно связать этот viewController с вашим настраиваемым NavigationController, поэтому в вашем методе viewDidLoad для вашего обычного viewController сделайте следующее:
источник
Вот еще один способ, который я реализовал (не тестировал его с помощью разматывающего перехода, но он, вероятно, не будет отличаться, как другие заявляли в отношении других решений на этой странице), чтобы родительский контроллер представления выполнял действия до того, как дочерний VC он нажал выскакивает из стека представления (я использовал его на пару уровней ниже исходного UINavigationController). Это также можно использовать для выполнения действий до того, как childVC будет вытолкнут. Это дает дополнительное преимущество работы с кнопкой возврата системы iOS вместо необходимости создавать пользовательский UIBarButtonItem или UIButton.
Попросите родительский VC принять
UINavigationControllerDelegate
протокол и зарегистрироваться для сообщений делегата:Реализуйте этот
UINavigationControllerDelegate
метод экземпляра вMyParentViewController
:Если вы укажете конкретную функцию обратного вызова в приведенном выше
UINavigationControllerDelegate
методе экземпляра}
источник
Вот что у меня работает в Swift:
источник
Если вы используете раскадровку и выходите из push-перехода, вы также можете просто переопределить
shouldPerformSegueWithIdentifier:sender:
.источник