Смешайте метод делегата Objective C с быстрым файлом - PullRequest
0 голосов
/ 25 октября 2018

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

Проблема в том, что я установил параметры просмотра в файле делегата следующим образом:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()

    let layout = UICollectionViewFlowLayout()
    window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))

    return true
}

Но так как мой основной файл делегата проекта находится в Objective-C, я не знаю, как заставить это работать в моем файле Swift в проекте Objective-C.Я попытался установить представление в файле viewDidLaunch.Но это не работает.Поэтому я спрашиваю себя, возможно ли на самом деле установить код для моего файла swift в методе делегата Objective-C в target-c.Но для моего проекта я хотел бы установить параметры просмотра внутри файла swift.Вот что я попробовал до сих пор:

import UIKit

class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

var window: UIWindow?

override func viewDidLoad() {
    super.viewDidLoad()

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()

    let layout = UICollectionViewFlowLayout()
    window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))

    navigationItem.title = "Home"

    collectionView?.backgroundColor = UIColor.white

    collectionView?.register(VideoCell.self, forCellWithReuseIdentifier: "cellId")
}

//number of items
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath)

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: 200)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}
}

class VideoCell: UICollectionViewCell{
override init(frame:CGRect){
    super.init(frame: frame)
    setupViews()
}

let thumbnailImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.backgroundColor = UIColor.blue
    return imageView
}()

let userProfileImageView: UIImageView = {
    let imageView = UIImageView ()
    imageView.backgroundColor = UIColor.green
    return imageView
}()

let separatorView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.black
    return view
}()

let titleLabel: UILabel = {
    let label = UILabel()
    label.backgroundColor = UIColor.purple
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

let subtitleTextView: UITextView = {
    let textView = UITextView()
    textView.backgroundColor = UIColor.red
    textView.translatesAutoresizingMaskIntoConstraints = false
    return textView
}()

func setupViews(){
    addSubview(thumbnailImageView)
    addSubview(separatorView)
    addSubview(userProfileImageView)
    addSubview(titleLabel)
    addSubview(subtitleTextView)

    //Abstand zum Bildschirmrand (Blau)
    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: thumbnailImageView)

    //Grün
    addConstraintsWithFormat(format: "H:|-16-[v0(42)]", views: userProfileImageView)

    //vertical constraints / v0 = Blau höhe / v1 = Grün höhe / v2 = Linie höhe
    addConstraintsWithFormat(format: "V:|-32-[v0(75)]-8-[v1(44)]-16-[v2(1)]|", views: thumbnailImageView, userProfileImageView, separatorView)

    //Abtrennung zwischen Zellen /zweite Zeile wird in "Große Fläche" umgesetzt
    addConstraintsWithFormat(format: "H:|[v0]|", views: separatorView)

    //top constraint
    addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .top, relatedBy: .equal, toItem: thumbnailImageView, attribute: .bottom, multiplier: 1, constant: 8))
    //left constraint
    addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .left, relatedBy: .equal, toItem: userProfileImageView, attribute: .right, multiplier: 1, constant: 8))
    //right constraint
    addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .right, relatedBy: .equal, toItem: thumbnailImageView, attribute: .right, multiplier: 1, constant: 0))
    //height constraint
    addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 0, constant: 20))


    //top constraint
    addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .top, relatedBy: .equal, toItem: titleLabel, attribute: .bottom, multiplier: 1, constant: 4))
    //left constraint
    addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .left, relatedBy: .equal, toItem: userProfileImageView, attribute: .right, multiplier: 1, constant: 8))
    //right constraint
    addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .right, relatedBy: .equal, toItem: thumbnailImageView, attribute: .right, multiplier: 1, constant: 0))
    //height constraint
    addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 0, constant: 20))

    thumbnailImageView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

extension UIView {
func addConstraintsWithFormat(format: String, views: UIView...){
    var viewsDictionary = [String: UIView]()
    for (index, view) in views.enumerated(){
        let key = "v\(index)"
        view.translatesAutoresizingMaskIntoConstraints = false
        viewsDictionary[key] = view
    }

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: viewsDictionary))

}
}

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Это просто не безопасно делать изнутри viewDidLoad в контроллере представления, и вы даже не должны пытаться это делать.

Это потому, что возможно выполнение viewDidLoad несколько раз .

Если это произойдет, оно заменит ваше окно и rootViewController новыми экземплярами в середине выполнения вашего приложения (глядя на пользователя, как если бы приложение сбросило само себя).

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

Однако вы все равно можете написать большую часть кода в Swift.

Во-первых,создайте расширение Swift в UIWindow, которое включает функцию класса, которая инициализирует и настраивает ваше окно, а затем возвращает его.Убедитесь, что расширение доступно Objective-C, добавив @objc к объявлению:

@objc extension UIWindow {
    class func setRootHomeViewController() -> UIWindow {
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.makeKeyAndVisible()
        let layout = UICollectionViewFlowLayout()
        window.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))
        return window;
    }
}

В вашем делегате приложения Objective C вам необходимо импортировать заголовок Swift и вызвать новый UIWindow метод класса, который вы определили.Присвойте возвращенный объект окна свойству window делегата приложения.

#import "YourProjectName-Swift.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    _window = [UIWindow setRootHomeViewController];

    return YES;
}

@end

Это всего одна строка кода Objective-C, но это необходимо, поскольку делегат приложения является единственным безопасным местом для этого.

0 голосов
/ 25 октября 2018

В общем, чтобы сделать быстрые классы доступными в target-c .
Также полезным для меня был еще один вопрос / ответ по стеку .

Но датьмысль о фундаментальных изменениях: может быть, лучше создать новое приложение в swift и подключиться к старым классам через заголовок brindging .Документация действительно полезна.

В будущем будет проще добавить новые элементы в swift и использовать новые функции.

...