2016-01-24 3 views
4

В тройку ответов можно решить мои вопросы. Трудно выбрать, какой из них лучше. Итак, я просто выбираю того, кто первым отвечает на мой вопрос. Извините за любителя и iOSEnthusiatic. Спасибо за помощь. Я ценю это.Перезагрузите и не перезагрузите, если нажать обратно с разных контроллеров. Swift

enter image description here

ViewController 1 имеет вид таблицы.

Мой вопрос заключается в том, чтобы перезагрузить вид таблицы, только если я нажимаю назад от вида контроллера 2, а не перезагружать вид таблицы, если я нажимаю назад от просмотра контроллера 3.

Прямо сейчас, мой код для кнопки возврата является

@IBAction func backButtonTapped(sender: AnyObject) { 
    self.dismissViewControllerAnimated(true, completion: nil) 
} 

в контроллере представления 1. Я знаю, что вид таблицы будет перезагружен с любой вид контроллера 2 или 3

override func viewDidAppear(animated: Bool) { 
    loadTable() 
} 

Я попытался поставить loadTable() в viewDidLoad и попробуйте написать приведенный ниже код для кнопки «Назад» в контроллере 2, но он не работает.

let storyboard = UIStoryboard(name: "Main", bundle: nil) 
let controller = storyboard.instantiateViewControllerWithIdentifier("UserHomePageViewController") as! UserHomePageViewController 
controller.viewDidLoad() 

Любое предложение, что мне следует делать? Спасибо за помощь.

EDIT:

Я думаю, что это простой способ сделать это, но он все еще не работает, как я думал. Я думаю, это потому, что viewDidAppear выполняется до вызова reloadTableBool. Верный? Есть ли способ исправить это? Спасибо. Вы поможете получить оценку.

class 2ViewController 
@IBAction func backButtonTapped(sender: AnyObject) { 
     let storyboard = UIStoryboard(name: "Main", bundle: nil) 
     let controller = storyboard.instantiateViewControllerWithIdentifier("1ViewController") as! 1ViewController 
     print("viewcontroller2 before call: \(controller.reloadTableBool)") 
     controller.reloadTableBool = false 
     print("viewcontroller2 after call: \(controller.reloadTableBool)") 
     self.dismissViewControllerAnimated(true, completion: nil) 
    } 
class 1ViewController 
var reloadTableBool = true 
override func viewDidAppear(animated: Bool) { 
    print("viewcontroller1: \(reloadTableBool)") 
    if reloadTableBool == true { 
     loadTable() 
    } 
} 

Когда я нажимаю назад на вид контроллера 2, он печатает

viewcontroller2 before call: true 
viewcontroller2 after call: false 
viewcontroller1: true 
+0

Вы используете кнопку назад вы получаете от навигационного контроллера или вы создали один, и добавил его вручную? – Eendje

+0

Я перетаскиваю элемент панели бара в панель навигации и создаю функцию для этой кнопки как «назад». Думаю, я создаю его вручную. –

+0

На ваших снимках экрана показано, что вы используете навигационный контроллер. Почему бы вам не использовать кнопку «Создать в задней панели»? – Eendje

ответ

2

Если отображение VC2 выполняется VC1 и всегда обязательно недействительными данные в VC1, вы можете сделать следующее:

  • добавить needsReload логическую переменную в инстанс VC1
  • установить его на true, когда вы показываете vc2 (и при instanciating vc1, например, в awakeFromNib, если он поступает из раскадровки)
  • только выполняет содержимое loadTable, если needsReload истинно (возможно, реорганизуйте эту логику в)
  • не забудьте установить needsReload ложь в конце loadTableIfNeeded

Эта модель недействительности находится во UIKit, смотри, например UIView setNeedsLayout/layoutIfNeeded. Преимущество состоит в том, что даже если несколько событий приводят к недействительности данных, они будут только обновляться, когда вам это нужно.

В вашей ситуации это имеет дополнительное преимущество в сохранении логики, содержащейся в vc1, и не создавая ненужной связи между вашими VC, что всегда хорошо.

--- UPDATE: пример реализации (ObjC но вы получите идею)

Вам нужно только справиться с этим в VC1, забыть обо всех кнопку назад вещи в VC2. Эта реализация будет отмечать VC1 для перезагрузки, как только VC2 будет представлен, но фактически перезагрузится только на viewWillAppear, когда VC2 будет уволен.

--- UPDATE 2: Добавлена ​​условная перезарядка, основанную на делегат обратного вызов

Обратите внимание, что _needsReload теперь установлен в делегат обратного вызова, а не когда VC2 впервые представлен. Вместо этого мы устанавливаем VC1 в качестве делегата VC2. (_needsReload логика на самом деле нет необходимости, используя этот метод, сохранил его для справки)

//VC2: add a delegate to the interface 

@class VC2; 

@protocol VC2Delegate 
- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges; 
@end 

@interface VC2 
@property (nonatomic, weak) id<VC2Delegate> delegate 
@end 

@implementation VC2 

- (IBAction) finishWithChanges 
{ 
    [self.delegate viewController:self didFinishEditingWithChanges:YES]; 
} 

- (IBAction) finishWithoutChanges 
{ 
    [self.delegate viewController:self didFinishEditingWithChanges:NO]; 
} 

@end 

//VC1: implement the VC2Delegate protocol 

@interface VC1() <VC2Delegate> 
@end 

@implementation VC1 
{ 
    BOOL _needsReload 
} 

- (void) awakeFromNib 
{ 
    //adding this for completeness but the way you did it in Swift (at init) is correct 
    [super awakeFromNib]; 
    _needsReload = YES; 
} 

- (void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self reloadTableIfNeeded]; 
} 

- (IBAction) displayVC2 
{ 
    VC2* myVC2 = ... //instanciate your VC2 here 
    myVC2.delegate = self; //set as the delegate of VC2 
    [self presentViewController:myVC2 animated:YES completion:nil]; 
} 

- (void) viewController:(VC2*)myVC2 didFinishEditingWithChanges:(BOOL)hasChanges 
{ 
    _needsReload = hasChanges; 
    [self reloadTableIfNeeded]; 
} 

- (void) reloadTableIfNeeded 
{ 
    if (_needsReload) { 
     [self.tableView reloadData]; 
     _needsReload = NO; 
    } 
} 

@end 
+0

Я тоже это сделал, но кажется, что viewDidAppear выполняется до вызова reloadTableBool. Не могли бы вы взглянуть на мое обновление? –

+0

@PakHoCheung, пожалуйста, просмотрите мое обновление. – amadour

+0

Я понял. Работа. Спасибо за помощь :) –

3

Вот link на вопрос я ответил пару дней назад. Используйте делегат контроллера навигации для обращения к кнопке «Назад». В вашем втором контроллере представления установите делегата на себя и перезагрузите табличное представление, когда вы нажмете кнопку «Назад».

override func viewDidLoad() { 
    super.viewDidLoad() 

    navigationController?.delegate = self 
} 

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { 
    if let controller = viewController as? FirstViewController { 
     controller.tableView.reloadData() 
    } 
} 

Примечание: Я предполагаю, что вы используете кнопку назад навигационного контроллера здесь.

EDIT: Еще один пример с помощью добавленных вручную кнопку назад:

@IBAction func backButtonTapped(sender: AnyObject) { 

    if let viewControllers = app.window?.rootViewController?.childViewControllers { 
     viewControllers.forEach { ($0 as? FirstViewController)?.tableView.reloadData() } 
    } 

    self.dismissViewControllerAnimated(true, completion: nil) 
} 

Видя, как вы используете навигацию контроллер:

@IBAction func backButtonTapped(sender: AnyObject) { 

    navigationController?.viewControllers.forEach { ($0 as? FirstViewController)?.tableView.reloadData() } 

    self.dismissViewControllerAnimated(true, completion: nil) 
} 
+0

Привет. Не могли бы вы увидеть мое редактирование?Я думаю, что это простой способ сделать это, поскольку я могу просто использовать Bool, но кажется, что viewDidAppear выполняется до вызова reloadTableBool? –

+0

На самом деле мой подход должен быть самым простым и, возможно, самым чистым, по сравнению с тем, что нужно иметь в виду отправлять «Bool» каждый раз, когда вы переходите к своему первому виду. Работали ли какие-либо из моих предложений? Теперь я посмотрю ваше редактирование. – Eendje

+0

Причина, по которой ваш 'Bool' не работает, заключается в том, что вы создаете новый экземпляр' UserHomePageViewController' и меняете вещи ** только ** для этого экземпляра. Вы хотите изменить «Bool» в существующем экземпляре 'UserHomePageViewController'. Используйте мои примеры, и если вы настаиваете на использовании 'Bool', замените перезагрузку таблицы на' Bool'. – Eendje

1

Вы можете использовать уведомления подход легко для этого.

Добавить наблюдателя в свой 1-й ViewController в режиме viewDidLoad.

NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadTable:", name: "reloadTable", object: nil) 

func reloadTable(notification : NSNotification){ 


let isReload : NSNumber = notification.userInfo!["isReload"] as! NSNumber 

    if (isReload.boolValue) { 
     self.tableView.reloadData() 
    } 
} 

Затем опубликовать уведомление, как это с вашей 2-й и 3-й ViewController соответственно при вызове dismissViewController.

// From 2nd viewcontroller 

NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: false)]) 

// From 3rd viewcontroller 
NSNotificationCenter.defaultCenter().postNotificationName("reloadTable", object: nil, userInfo: ["isReload" : NSNumber(bool: true)]) 
+0

Это что-то вроде моего редактирования? –

+0

Нет! вы должны использовать этот подход для достижения желаемого результата. – iOSEnthusiatic

+0

UM. Сожалею. Я не совсем понимаю цель C –

Смежные вопросы