2016-12-21 2 views
2

У меня есть UIViewController (Главное меню), которое отображается после того, как мой другой UIViewController (Экран загрузки) завершает загрузку/синхронизацию данных из Интернета. У моего главного меню возникают проблемы, так как он не всегда отображает все UIButton, которые находятся на экране, когда он появляется! Существует несогласованность, 1 из каждых 10 раз нагрузок главного меню, все UIButtons появятся.Swift 3 - UIView не всегда отображает его содержимое

Вот как вид должен выглядеть: Correct View

Вот как вид обычно проявляется: How it shows up

Я могу понять, где UIButtons должно быть и пошевелить пальцем в сторону, и они будут появляться. Я также могу указать, где они должны быть, и мои segues все равно будут срабатывать, но UIButtons не будут автоматически отображаться. Похоже, This

Я попытался добавить функцию MainMenuView.setNeedsDisplay() в функцию ViewDidLoad, и это не помогло. Я также создал тестовый UIButton в представлении, который запускает команду MainMenuView.setNeedsDisplay(), но скрытые UIButtons остаются скрытыми.

Если я покину экран на холостом ходу в течение примерно 30 секунд, все UIButtons будут случайным образом отображаться без необходимости вручную их отображать.

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

Edit: Главное меню Code - (ссылки Strong)

import UIKit 
import CoreData 

class MainMenuViewController: UIViewController { 

    // MARK: References 
    @IBOutlet var btnGasManifolds: UIButton! 
    @IBOutlet var btnAirCompressors: UIButton! 
    @IBOutlet var btnVacuumPumps: UIButton! 
    @IBOutlet var btnUnitConversion: UIButton! 
    @IBOutlet var btnCFMCalculator: UIButton! 
    @IBOutlet var mainMenuView: UIView! 

    var userData = [NSManagedObject]() 

    // MARK: Functions 

    override func viewDidLoad() { 
     var name = String() 
     for duserData in userData { 
      name = duserData.value(forKey: "nameFull") as! String 
     } 
     print("Main Menu\n->\(name)") 
     backgroundSetup() 
    } 

    override func viewDidAppear(_ animated: Bool) { 
     mainMenuView.setNeedsDisplay() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    @IBAction func btnTest(_ sender: Any) { 
     mainMenuView.setNeedsDisplay() 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any!) { 
     if segue.identifier == "settingsSegue" { 
      let destination = segue.destination as! SettingsViewController 
      destination.userData = userData 
     } 
    } 

    // Background Setup 
    func backgroundSetup() { 
     let background = UIImage(named: "Data Screens") 

     var imageView : UIImageView! 
     imageView = UIImageView(frame: view.bounds) 
     imageView.contentMode = UIViewContentMode.scaleAspectFill 
     imageView.clipsToBounds = true 
     imageView.image = background 
     imageView.center = view.center 
     view.addSubview(imageView) 
     self.view.sendSubview(toBack: imageView) 
    } 
} 
+0

Это поможет, если вы разместите свой код для этого вида. Благодарю. – dfd

+0

@dfd Я добавил код. Я экспериментировал с mainMenuView.setNeedsDisplay, поэтому вы можете игнорировать его. –

ответ

1

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

Запустить код в главной очереди отправки.

+0

Прежде чем я разместил этот вопрос, я попытался вызвать функцию performSegue с моего экрана загрузки с DispatchQueue.Main.async (я также попробовал синхронизацию), и это не устранило мою проблему. UIButtons не создаются программно, а на раскадровке внутри xCode. Как я могу поместить код, который создает и показывает кнопки в главной очереди? Создать программные кнопки и запустить их в главной очереди? –

+0

OK. Я не уверен, что еще вижу достаточный код, но вот мое занятие. Во-первых, ** что-то **, очевидно, вызывает время (которое отсутствует здесь, если вы не тромбировали свой собственный код со всеми setNeedDisplay и другими вызовами жизненного цикла представления и segue). Я предполагаю, что если вы вычеркиваете весь этот код и ** все еще ** видите проблемы (вы, вероятно, будете), мы говорим об извлечении db. Если да, то это то, что вам нужно, чтобы закодировать против ** до ** segue. Установите это в своем первом VC (возможно, выпустите предупреждение для пользователя), затем настройте свои второй свойства VC и segue. – dfd

+0

В итоге я получил свои элементы пользовательского интерфейса. Мне пришлось запускать загрузочный экран, как этот 'DispatchQueue.main.async {datasyncfunction(); seguefunction()} ' –

0
dispatch_async(dispatch_get_main_queue(),{ 
    //do some work 
}) 

ИЛИ Override один из методов из ViewWillLayoutSubviews и ViewDidLayoutSubviews соответственно и запустить свой код в этих методах.

+0

Где я могу поместить код отправки? Какой контент я могу разместить внутри?Мои UIButtons не создаются программно, если это имеет значение. Нужно ли их создавать программно внутри основной очереди? –

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