繁体   English   中英

将Objective-C委托方法与swift文件混合

[英]Mix Objective-C delegate method with swift file

我开始在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
}

但是因为我的主要Project委托文件位于Objective-C中,所以我不知道如何在Objective-C Project的Swift文件中使用它。 我尝试在viewDidLaunch文件中设置视图。 但这不起作用。 所以我问自己,是否真的可以在Objective-C的Objective-C委托方法中为我的swift文件设置代码。 但是对于我的项目,我想在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))

}
}

通常, 可以在Objective-C中使用Swift类
对我也有帮助的另一个问题是栈

但是请考虑一下根本的变化:最好是迅速创建一个新应用,然后通过brindging header连接到旧类。 文档确实很有帮助。

将来,迅速添加新元素并使用新功能将变得更加容易。

在视图控制器的viewDidLoad中执行此操作绝对是不安全的,您甚至不应尝试这样做。

这是因为viewDidLoad可以多次执行。

如果发生这种情况,它将在应用执行过程rootViewController窗口和rootViewController替换为新实例(对用户来说,就像应用已重置一样)。

您需要从应用程序委托初始化窗口和根控制器,别无选择。

但是,您仍然可以在Swift中编写大多数代码。

首先,在UIWindow上创建一个Swift扩展,其中包括一个类函数,该函数初始化并配置您的窗口,然后将其返回。 通过在声明中添加@objc ,确保可由Objective-C访问该扩展名:

@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代码,但是这是必需的,因为应用程序委托是唯一安全的地方。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM