Проблема с экземпляром класса

#ios #swift

#iOS #swift

Вопрос:

Моя цель — при нажатии кнопки в ViewController 2 экран будет отключен, и я заполню своих делегатов UIColor / UIImage, правильно? Хорошо, тогда после завершения просмотра ViewController 1 установит цвет фона на красный. Однако у меня возникли проблемы, когда я попытался создать экземпляр «Escolha VC» в ViewController 1. Я опубликую оба класса выше:

ViewController 1

 import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var labelNome: UILabel!
    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func BotaoStart(_ sender: Any) {

        let selectionVC = EscolhaVC()

   selectionVC.selectionDelegate = self //I got no crashes, 
  //but the problem is that a black screen comes in instead "EscolhaVC"

        present(selectionVC, animated: true, completion: nil)
    }

}

extension ViewController:DidselectInformationDelegate {
    func selectedOptions(imagem: UIImage, cor: UIColor) {
        self.imageView.image = imagem
        self.view.backgroundColor = cor
    }
  

Что я делаю не так?

ViewController 2

 import UIKit

protocol DidselectInformationDelegate {
    func selectedOptions(imagem:UIImage, cor:UIColor)
}

class EscolhaVC: UIViewController {


    var selectionDelegate:DidselectInformationDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

    }


    @IBAction func botaoLadoBom(_ sender: Any) {
        selectionDelegate?.selectedOptions(imagem: #imageLiteral(resourceName: "ladoBom"), cor: .green)
        dismiss(animated: true, completion: nil)
    }



    @IBAction func botaoLadoNegro(_ sender: Any) {
        selectionDelegate?.selectedOptions(imagem: #imageLiteral(resourceName: "ladoNegro"), cor: .red)
        dismiss(animated: true, completion: nil)
    }
  

Комментарии:

1. Что вы подразумеваете под «согласованием делегатов»? Что вы подразумеваете под «разработанным как полный код»? У вас есть пример фрагмента кода, с которым вы столкнулись?

2. Привет, Роб. Соответствие, которое я имел в виду как (делегат = self), и выполненное как «полный код», представляет собой проект без раскадровки. Мой вопрос: как я могу создать экземпляр ViewControllers другим способом, а не как указано выше?

3. С let vc = ViewControllerType(parameters...) помощью . Я не совсем понимаю, в чем вопрос. Есть ли причина, по которой вы пытаетесь удалить раскадровку?

4. Да, потому что у меня есть другие проекты, которые не используют раскадровку

5. Что, если у меня нет никаких параметров в другом классе? Допустим, у меня просто есть протокол. Как мне создать экземпляр этого класса?

Ответ №1:

Ну, инициализация — очень обширная тема в Swift. Ознакомьтесь с этой документацией для получения полного объяснения по этому вопросу. Но в качестве краткого резюме вам просто нужно вызвать любые параметры, которые требуются в любом из init типов типа (class или struct). В качестве примера рассмотрим следующий класс:

 class Foo {
  let a: Int
  let b: Int

  init() {
    a = 0
    b = 0
  }

  init(a: Int, b: Int) {
    self.a = a
    self.b = b
  }
}
  

У вас есть два способа создания экземпляра Foo объекта. Либо с помощью let foo = Foo() , либо что-то вроде let foo = Foo(a: 10, b: 20) . Не имеет значения, является ли это подклассом какого-либо другого класса, например UIViewController , подкласса. Не имеет значения, содержит он или нет свойство, типом которого является протокол. Если ваш UIViewController подкласс не определяет пользовательские инициализаторы, вы можете создать его, просто:

 let selectionVC = EscolhaVC()
  

Затем просто установите любое другое необходимое свойство впоследствии:

 selectionVC.selectionDelegate = self
  

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

Редактировать

Судя по вашему редактированию, это проблема не в создании экземпляра, а в стилизации вашего EscolhaVC . Когда вы создаете экземпляр из раскадровки, вы получаете контроллер представления со всеми видами, цветами и т. Д., Которые вы определили в interface builder. Но вам нужно это сделать самостоятельно, если вы создаете экземпляр контроллера представления с помощью его инициализатора. Например, попробуйте установить EscolhaVC цвет фона вашего представления, сделайте что-нибудь еще, и вы увидите, что все хорошо:

 class EscolhaVC: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .red
  }
}
  

Комментарии:

1. Привет, @ajeferson. Я только что обновил код, давайте посмотрим, смогу ли я прояснить свою ошибку. Не могли бы вы проверить ниже, пожалуйста? Кстати, большое спасибо за ваш ответ!

2. Конечно. На самом деле это не вопрос создания экземпляра, а то, как вы настраиваете свой EscolhaVC контроллер представления. Например, попробуйте установить цвет фона в viewDidLoad EscolhaVC (view.backgroundColor = .red).

3. Моя цель — при нажатии кнопки в ViewController 2 экран будет закрыт, и я заполню свои делегаты, правильно? Хорошо, тогда после завершения просмотра ViewController 1 установит цвет фона на красный. Однако у меня возникли проблемы, когда я попытался создать экземпляр «Escolha VC» в ViewController 1.

4. Ну, теперь я в замешательстве. Я заметил, что в EscolhaVC у вас есть функции действий (@IBFunction). Вам также необходимо программно добавить целевые объекты к этим функциям. Но для меня это выглядит нормально, когда вы создаете экземпляр EscolhaVC в контроллере первого вида.

5. Говорю вам, с вашим кодом все в порядке. Показывать черный экран нормально, поскольку вы не применяете какой-либо стиль или не загружаете контроллер представления из конструктора интерфейсов. Если вы хотите, чтобы что-то отображалось, вам нужно это программно? Даже @IBFunctions не будут работать, поскольку они ни к чему не привязаны.