2015-08-03 4 views
2

Я все еще на ранней стадии разработки Swift. Я пытаюсь создать функцию, когда я нажимаю кнопку на экране, после чего я получаю запрос от iPhone, чтобы разрешить местоположение, и когда я нажимаю «Разрешить», я автоматически перехожу на другой экран.Как я могу вызвать функцию из существующего класса View Controller?

До сих пор я сделал следующие вещи:

  • создал отдельный класс («Пользователь»), где все функции определения местоположения обрабатываются
  • Setup кнопку на первом контроллере представления, соответствующий ему IBAction, что вызывает быструю функцию определения местоположения от «пользователя»
  • Добавлены раскадровки идентификаторов для первого и второго контроллера представления
  • создал функцию («changeScreen») в первом классе контроллера вида, который выполняет навигацию к другой точке зрения
  • Настройки слушатель в классе «User», когда пользователь нажал разрешить местоположение, который затем называет «changeScreen» функцией

Я думаю, что есть еще один способ сделать это (вызов какого-то обработчик завершения) и я играл с этим в течение 1-2 часов, и ничего не работало. До сих пор это решение почти полностью работает, но я получаю следующее сообщение об ошибке:

Warning: Attempt to present ____ on _____ whose view is not in the window hierarchy!

Вот код в моем классе «Пользователь»

class User: NSObject, CLLocationManagerDelegate { 

func getLocation(){ 

    // For use in foreground 
    locationManager.requestWhenInUseAuthorization() 

    locationManager.delegate = self 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.requestWhenInUseAuthorization() 
    //locationManager.startUpdatingLocation() 

    println("hello location") 


} 

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status:CLAuthorizationStatus){ 

     if status == .AuthorizedWhenInUse { 

      locationManager.startUpdatingLocation() 

      firstView!.showSecondScreen() // this is where I call the other  class's function 

     } 
    } 
    } 

Вот код в моем первом классе View контроллера

var firstView: FirstView? = nil 

class FirstView: UIViewController { 

var newUser = User() 

override func viewDidAppear(animated: Bool) { 

    firstView = self.storyboard!.instantiateViewControllerWithIdentifier("firstView") as? FirstView 

// here i take the first view controller class and store it into a public variable 

} 

@IBAction func allowLocationBtn(sender: AnyObject) { 

    newUser.getLocation() // this is the first button clicked 

} 

func showSecondScreen(){ 

    let secondScreen = self.storyboard!.instantiateViewControllerWithIdentifier("SecondScreen") as! SecondScreen 

    self.presentViewController(secondScreen, animated: true, completion: nil ) 

} 

Пс. Я знаю, что я могу объединить весь код в один класс, и все могло бы работать так. Но я хочу сделать это «правильным» способом, иметь разные функциональные возможности в разных классах.

+1

Как вы показываете FirstView в окне? – Amit89

+0

Эй, Амит, я показываю FirstView на раскадровке, просто обычный объект View Controller, и я связал его с классом «FirstView». Отвечает ли это на ваш вопрос? – trixmasta

+0

- вам нужно установить 'first = self', не создавая новый viewcontroller – Azzaknight

ответ

1
  • попытка установить first = self, то не создавать новый вид-контроллер
  • при использовании раскадровки, лучше использовать перетекает, чтобы отобразить другой экран

Хотя правильная вещь здесь будет иметь UserDelegate Протокол

protocol UserDelegate { func displayOtherScreen() }

затем в User добавить var delegate: UserDelegate? и в locationManager функции вместо вызова firstView!.showSecondScreen вызов delegate?.displayOtherScreen()

Затем сделайте FirstView принять UserDelegate Протокол

class FirstView: UIViewController, UserDelegate { 
var newUser = User() 

override func viewDidAppear(animated: Bool) { 
    newUser.delegate = self 
    ... 
    } 
    ... 
    ... 
func displayOtherScreen() { 
    showSecondSceen() 
    } 

Теперь нет необходимости для первой переменной ..

+0

Ты буквально такой потрясающий. Это было ТОЧНО, что я искал. Просто реализовал это, и он работает плавно. Спасибо Azzaknight! – trixmasta

0

В идеале ситуации, которую вы пытаетесь обрабатывать несколькими MVC. Второй экран сам по себе должен отличаться от представления и должен иметь собственный контроллер просмотра модели. Таким образом, вы не нарушаете правила архитектуры MVC.Функцию ShowSecondScreen() следует контролировать с помощью SecondViewController.

После того, как вы определили это несколько MVC, вы можете подключить их. Есть несколько способов сделать это - UISplitViewController, UITabViewController, UINavigationViewController. В вашем случае UINavigationViewController кажется лучшим вариантом. Вы можете добавить контроллер навигации для подключения MVC с помощью Editor -> Embed на class FirstView. Это сделало бы FirstView controller вашим rootViewController.

Затем добавьте segue из вашей кнопки на FirstView к контроллеру для SecondScreen SecondViewController т.е.

class FirstView: UIViewController { 
    override func prepareForSegue(..) { 
     if let secondControllerObject = segue.destinationViewController as? SecondViewController { 
      if let identifier = segue.identifier { 
       switch identifier { 
         case "<your_buttons_identifier_string" : secondControllerObject .callToSecondScreen() 
/* Now will move the Second View to the top of the MVC stack and you 
will be also able to go back to first view as you have a 
Navigation Controller hooked up.*/ 
/* callToSecondScreen - should be a controller object displaying the 
controlling and displaying contents in the second screen's view. 
Data for second screen's view will come from its Model */ 

     } 
+0

Спасибо, чувак, это здорово. Однако я не хочу, чтобы представление менялось при нажатии обычной кнопки, на самом деле, когда кнопка «Разрешить» от iPhone «Разрешите ли вы разместить»? незамедлительный. Как я могу проверить эту кнопку? Или как я могу запустить этот сеанс из класса User? – trixmasta

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