2019-02-26 14:16:29 wei78008023 阅读数 1525
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

    这是一门快速入门iOS开发的课程,目的是让大家快速学会,iOS开发环境搭建,和iOS一些基础知识,最后完成一个小项目。 项目信息 提供完整的Git提交历史,和每节视频一一对应,目前有41次提交,355行注释,271行代码(不包含可视化布局文件,纯Swift和Objective-C代码)。

    2911 人正在学习 去看看 任苹蜻

之前在开发是遇到了在OC文件中调用Swift对象的变量调用不到的问题,这里总结一下:

1.首先我们一个Swift项目TestProject。

2.建立一个Swift的文件继承自NSObject名字为SwiftFile.swift,并声明一个字符串变量swiftName。

import UIKit

class SwiftFile: NSObject {

    var swiftName = ""
}

3.建立一个OC的文件ObjectFile,并导入“HFSTeacher-Swift.h”(OC想要调用Swift需要导入此文件)如何配置以及导入原因可以自行查询。

#import "ObjectFile.h"
#import "HFSTeacher-Swift.h"

@implementation ObjectFile

-(void)oneMethod
{
    SwiftFile *swiftFile = [[SwiftFile alloc]init];
    NSLog(@"%@",swiftFile.swiftName);
}

@end

这个时候会报错,说在SwiftFile中找不到swiftName成员。

4.这个时候需要在SwiftFile.swift中加入一个声明@objcMembers以表示文件中成员可以被OC调用:

import UIKit

@objcMembers
class SwiftFile: NSObject {

    var swiftName = ""
}

5.如此则大功告成!

2015-11-13 10:06:44 lvdezhou 阅读数 1579
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

    这是一门快速入门iOS开发的课程,目的是让大家快速学会,iOS开发环境搭建,和iOS一些基础知识,最后完成一个小项目。 项目信息 提供完整的Git提交历史,和每节视频一一对应,目前有41次提交,355行注释,271行代码(不包含可视化布局文件,纯Swift和Objective-C代码)。

    2911 人正在学习 去看看 任苹蜻

1、oc工程调用swift-----自动创建桥接头文件

创建一个oc工程:


设置Product Module Name = 工程名



创建一个swift文件:

点击自动创建桥接头文件:



设置Objective-C Bridging Header 如下图:



至此,我们可以在oc中调用swift了

测试代码:


import Foundation

class Student: NSObject {
    var name : String = "dzl"
    var age : Int = 22
}

在oc中引入头文件  "工程名-swift.h" 就可以使用swift中的类了

注:这个头文件是不可见的

#import "ViewController.h"

#import "OCuseSwift1-swift.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    Student * s1 = [[Student alloc] init];
    NSLog(@"%@", s1.name);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

输出:

2015-11-13 10:01:32.250 OCuseSwift1[1040:20007] dzl

此时swift也是可以引用OC的,只需将swift需要使用的oc类头文件在桥接头文件中引入即可,






2、oc工程调用swift-----手动创建桥接头文件


首先创建一个oc工程,与上面相同

然后创建一个swift文件,但是不选择创建桥接头文件,如图:



然后手动创建桥接头文件,就相当于创建一个普通的头文件一样,只是命名一定要严格按照规则:



工程设置中指定桥接头文件:


经测试,oc引用swift或者swift引用oc都是可以的,测试方法与上面相同,这里不再赘述。



3、swift工程调用-----自动创建桥接头文件 和 手动创建桥接头文件,基本与上面操作一直,不再详述




其实桥接头文件里面引入oc头文件,是为了swift可以访问oc文件,

在oc中引入   工程名-swift.h   文件  是为了oc可以访问swift,但这个文件是不可见的,不过可以通过command+鼠标左键查看该文件



2016-11-15 17:41:47 zhonggaorong 阅读数 6156
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

    这是一门快速入门iOS开发的课程,目的是让大家快速学会,iOS开发环境搭建,和iOS一些基础知识,最后完成一个小项目。 项目信息 提供完整的Git提交历史,和每节视频一一对应,目前有41次提交,355行注释,271行代码(不包含可视化布局文件,纯Swift和Objective-C代码)。

    2911 人正在学习 去看看 任苹蜻

最新一些学妹问起,所以抽点时间来写的,适合入门级别的swift 与 OC 混编 的程序猿。  

本文章将从两个方向分别介绍 OC 与 swift 混编  


1. 第一个方向从 swift工程 中引入 oc类 

    1. 1 如何在swift的类中使用oc类
    1.2  如何在swift中实现oc的代理方法
    1.3   如何在swift中实现oc的Block回调

2. 第二个方向从OC工程中引入swift类

    2.1  如何在OC类中使用swift类
    2.2   如何在OC中实现swift的代理方法
    2.3   如何在OC中实现swift中类似Block回调


下面是具体的实现过程:

 1.1  如何在swift的类中使用oc类? 

1.  swift工程中引入OC类。 具体实现过程。

    1.1 新建一个swift工程类。 取名 swiftOrOC

    1.2  实现的功能为 :  从swift. viewController.swift 中 push到 OC语言 secondViewController 控制器

1.2.1  新建SecondViewController 类 。

        

     1.2.2 建立桥接文件。 (很重要)


    一定要记得点击这个按钮。 

       1.2.3  接下来工程目录如下:

       

     1.2.4 接下来就可以实现具体的跳转功能了。 

      ViewController.swift中具体实现

     

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var hintLabel: UILabel!  //稍后用来显示回调
    
    // push 到 oc controller
    @IBAction func pushAction(_ sender: AnyObject) {
        let secondVC = SecondViewController.init()
        self.navigationController?.pushViewController(secondVC, animated: true)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

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


}


1.2 如何在swift中实现oc的代理方法

       1.2.1 首先在 SecondViewController.h 中声明一个协议。具体代码

        

#import <UIKit/UIKit.h>

@protocol SecondDelegate <NSObject>

-(void)refreshHintLabel:(NSString *)hintString;

@end

@interface SecondViewController : UIViewController

@property (nonatomic,weak)id<SecondDelegate> secondDelegate;
@end
     1.2.2 然后在SecondViewController.m中,通过一个UITextField,让用户输入内容,当用户点击返回的时候把输入框中的内容返回给对应的代理。具体代码如下

    

#import "SecondViewController.h"
#import "UIViewController+BackButtonHandler.h"

@interface SecondViewController ()
{
    UITextField *textField;
}
@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"oc";
    
    self.view.backgroundColor  = [UIColor whiteColor];
    
    textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
    textField.placeholder = @"请输入用户名";
    [self.view addSubview:textField];
    [textField.layer setBorderColor:[UIColor blackColor].CGColor];
    [textField.layer setBorderWidth:1.0];

    
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}
#pragma mark 返回上一页回调 ,将用户输入的用户名传回给 ViewController.swift
-(BOOL)navigationShouldPopOnBackButton{
    if ([_secondDelegate respondsToSelector:@selector(refreshHintLabel:)]) {
        [_secondDelegate refreshHintLabel: textField.text];
    }
    
    return YES;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
  1.2.3 接下来就非常简单了,让ViewController.swift只需要成为SecondViewController的代理,然后遵循她的协议,就可以了。 具体代码如下。

       1.2.3.1 遵循协议

  

     1.2.3.2 成为代理,并实现协议方法,更改controller.swift中hintLabel的text。

    // push 到 oc controller
    @IBAction func pushAction(_ sender: AnyObject) {
        let secondVC = SecondViewController.init()
        secondVC.secondDelegate = self;
        self.navigationController?.pushViewController(secondVC, animated: true)
    }
    
    // SecondViewControll的代理方法
    func refreshHintLabel(_ hintString: String!) {
        hintLabel.text = "secondView textView.text = " + hintString;
    }
    

 1.3   如何在swift中实现oc的Block回调

1.3.1 具体过程与1.2小节一样。 直接上代码。

        1.3.2 声明block;

         

typedef void(^RefreshHintLabelBlock)(NSString *hintString);

@interface SecondViewController : UIViewController
@property (nonatomic, copy) RefreshHintLabelBlock hintBlock;
@end

        1.3.3 block的回调。 SecondViewController.m中

#pragma mark 返回上一页回调 ,将用户输入的用户名传回给 ViewController.swift
-(BOOL)navigationShouldPopOnBackButton{    
    if (_hintBlock) {
        _hintBlock(textField.text);
    }
    return YES;
}

        1.3.4 在swift类中调用 oc的block.

    // push 到 oc controller
    @IBAction func pushAction(_ sender: AnyObject) {
        let secondVC = SecondViewController.init()
//        secondVC.secondDelegate = self;
        secondVC.hintBlock = {(t:String?)in
            self.hintLabel.text = "secondView textView.text = " + t!
        }
        self.navigationController?.pushViewController(secondVC, animated: true)
    }


   工程已上传到git上,git地址: https://github.com/zhonggaorong/SwiftOrOc/tree/master

2.  OC工程中引入swift类。 具体实现过程。

    耽误了不少时间, 今天才开始写oc工程中引入swift类。

    demo地址: 

  

     2.1  如何在OC类中使用swift类


       2.1.1   新建一个基于OC语言的工程 ,取名 OcOrSwiftTwo
       2.1. 2  实现的功能为 : 从oc类 viewcontroller中, push 至 swift语言 SecondViewController  ,然后SecondViewController可以通过代理或者swift闭包把值传回viewcontroller. 
       2.1.3   当前文件目录看下图:  (第四个箭头: 桥接文件)
        
  
    2.2   如何在OC中实现swift的代理与闭包Block方法
            
    2.2.1 如何在oc中引入swift类。#import "工程名-swift.h"
#import "OcOrSwiftTwo-swift.h"
   2.2.2 在secondViewController.swift 中实现代理与闭包,代码如下:
    注意: @objc(代理名)  才能在外部可见这个代理
 
import UIKit
import Foundation

// 必须加上@objc 代理才能在oc类中可见。
@objc(EditTextFieldDelegate)
protocol EditTextFieldDelegate:NSObjectProtocol {
    func editTextField(_ str: String) -> Void
}

@objc(SecondViewController)
class SecondViewController: UIViewController {

    var editorDelegate:EditTextFieldDelegate?
    var textField:UITextField?
    var addButton:UIButton?
    var pushButton:UIButton?
    
    typealias editorBlock = (_ t:String) -> Void
    var myEidtorBlock:editorBlock?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        textField = UITextField.init(frame: CGRect.init(x: 50, y: 60, width: 200, height: 50))
        textField?.placeholder = "输入返回首页的内容"
        self.view.addSubview(textField!)
        
        addButton = UIButton.init(type: .custom)
        addButton?.setTitleColor(UIColor.black, for: .normal)
        addButton?.setTitle("pop", for: .normal)
        addButton?.frame = CGRect.init(x: 50, y: 150, width: 200, height: 50)
        addButton?.layer.borderColor = UIColor.black.cgColor
        addButton?.layer.borderWidth = 1.0
        addButton?.addTarget(self, action: #selector(popAction), for: .touchUpInside)
        self.view.addSubview(addButton!)
        
        
        
        pushButton = UIButton.init(type: .custom)
        pushButton?.setTitleColor(UIColor.black, for: .normal)
        pushButton?.setTitle("push", for: .normal)
        pushButton?.frame = CGRect.init(x: 50, y: 250, width: 200, height: 50)
        pushButton?.layer.borderColor = UIColor.black.cgColor
        pushButton?.layer.borderWidth = 1.0
        pushButton?.addTarget(self, action: #selector(pushAction), for: .touchUpInside)
        self.view.addSubview(pushButton!)
        
    }
    
    func popAction() -> Void {
        
        if editorDelegate != nil {
            editorDelegate?.editTextField((textField?.text)!)
        }
        
        if ((self.myEidtorBlock) != nil){
            self.myEidtorBlock!((textField?.text!)!)
        }
        
        self.navigationController?.popViewController(animated: true)
    }
    
    
    func pushAction() -> Void {
        let three = ThreeViewController.init()
        self.navigationController?.pushViewController(three, animated: true)
        
    }     
    2.2.3   在oc类中viewcontroller.m 文件中实现SecondviewController.swift的相关代理与闭包(block). 代码如下:
   
#import "ViewController.h"
#import "OcOrSwiftTwo-swift.h"

@interface ViewController ()<EditTextFieldDelegate>
@property (nonatomic, strong) UITextField *showTextField;
@property (nonatomic, strong) UIButton *pushButton;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _showTextField = [[UITextField alloc]initWithFrame:CGRectMake(50, 100 , 200, 50)];
    _showTextField.placeholder = @"swift传回的文本内容";
    _showTextField.adjustsFontSizeToFitWidth = YES;
    _showTextField.enabled = NO;
    [self.view addSubview:_showTextField];
    
    _pushButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_pushButton.layer setBorderColor:[UIColor blackColor].CGColor];
    [_pushButton.layer setBorderWidth:1.0];
    [_pushButton setFrame:CGRectMake(50, 200, 200, 50)];
    [_pushButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_pushButton setTitle:@"push" forState:UIControlStateNormal];
    [_pushButton addTarget:self action:@selector(pushAction) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:_pushButton];
}




-(void)pushAction{
    SecondViewController *second = [[SecondViewController alloc]init];
    // second.editorDelegate = self;
    
    /*
      swift中的闭包回滴
     */
    second.myEidtorBlock = ^(NSString *str) {
        _showTextField.text = [NSString stringWithFormat:@"second传回信息: %@",str];
    };
    [self.navigationController pushViewController:second animated:YES];
}

#pragma mark swift中的代理
-(void)editTextField:(NSString *)str{
    _showTextField.text = [NSString stringWithFormat:@"second传回信息: %@",str];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


2017-03-17 13:51:27 u010407865 阅读数 20588
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

    这是一门快速入门iOS开发的课程,目的是让大家快速学会,iOS开发环境搭建,和iOS一些基础知识,最后完成一个小项目。 项目信息 提供完整的Git提交历史,和每节视频一一对应,目前有41次提交,355行注释,271行代码(不包含可视化布局文件,纯Swift和Objective-C代码)。

    2911 人正在学习 去看看 任苹蜻

网上有很多关于OC项目中使用Swift类的方法,但是亲自试了之后,发现不够详细,多次尝试后,终于找出详细的方法。
现把方法和遇到的问题,记录下来,方便其他同仁借鉴:

一、新建一个OC工程,工程名称自定,在这里我定义为OCAndSwiftDemo,如图:

新建项目架构图

二、在新建Swift类之前,进行相关设置,如图:

相关设置

三、在项目中,新建一个TestDemo的swift类,点击Create后,提示如图:

创建OC调用Swift类的桥接文件

选择Create Bridging Header,一定要选择这个,如果不选择,就引入不了Swift类,然后生成”项目名称-Bridging-Header.h”桥接文件

然后编辑Swift类,如果Swift类想要被OC发现,必须继承自NSObject,如图:

TestDemo类

四、调用Swift类,我们想要调用Swift类的方法里面引入头文件:”项目名称-Swift.h”,如图:

调用Swift类

注释:如果调用不了Swift类,可以先Shift+Command+R一下。

2019-03-25 14:27:53 lfdanding 阅读数 82
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

    这是一门快速入门iOS开发的课程,目的是让大家快速学会,iOS开发环境搭建,和iOS一些基础知识,最后完成一个小项目。 项目信息 提供完整的Git提交历史,和每节视频一一对应,目前有41次提交,355行注释,271行代码(不包含可视化布局文件,纯Swift和Objective-C代码)。

    2911 人正在学习 去看看 任苹蜻

最近在oc工程里要引用swiftMonkeypaws,需要使用oc调用swift技术,里面踩了很多坑,这里简单记录一下。

1、oc调用swift

oc调用swift其实很简单,google一下就有很多的教程,可以参考文章1、2、3、4。总体上就是在要调用swift代码的时候,引入头文件 “模块名-Swift.h”,这个头文件对外不可显示,需要手动导入。可以在 Build setting 中查看:
在这里插入图片描述
现在我们在 OC 中添加这个头文件:
在这里插入图片描述
我们需要查看一下swift到底可以调用那些方法和类。这个时候,我们可以点进这个头文件中去。进入头文件往下拉,可以看到暴露出来的 Swift 的类名和方法:
在这里插入图片描述

2、oc调用swift ,涉及cocoapods

上面完全是主工程里使用当然毫无难度,但是我要引入的swiftMonkeypaws是要以cocoapods方式进行引入,这里面就有很多的问题。

2.1 引入头文件名字不一样

头文件要引入的格式为 #import <产品名/模块名-Swift.h>,参考文章5,我们可以在 Build Settings 中查看:
在这里插入图片描述
2.2、头文件引入的位置
头文件如果引用在pods工程的起点文件中,还是会报找不到头文件的错误,这里面我没有深入研究pods工程的编译原则,但是不难猜出因为是在pods工程的起点文件中,还没有开始编译pod工程里的swift文件,所以就没有生成oc调用swift的接口文件,导致头文件找不到。我这边的临时解决办法就是把头文件引用移动到了其他的位置
在这里插入图片描述

3、oc引用swiftMonkeypaws

oc引用swiftMonkeypaws,网上的文章也很多,可以参考文章6、7、8、9、10。对于参考文章8,矫正一下

var paws: MonkeyPaws?

class MonkeyUIPaws: NSObject 
{        
    @objc public func showMonkeyPawsINUITest ( window: UIWindow ) -> () {
        paws = MonkeyPaws(view: window)    
    }

     @objc class func test() -> () {
        print("test")
    }
}

如果不这么修正,你会收到 unrecognized selector sent to instance,主要原因是因为把MonkeyPaws设置成局部变量以后,这个界面释放以后,MonkeyPaws也被释放,再调用MonkeyPaws的方法就会引发这个错误。所以要把MonkeyPaws设置到类外面。对于unrecognized selector sent to instance这个错误的详细描述可以参考文章11、12。

参考文章:

1、https://blog.csdn.net/studying_ios/article/details/70146879
2、https://www.jianshu.com/p/754396e7e1bd
3、https://www.jianshu.com/p/9f757a09eacd
4、https://www.jianshu.com/p/979ff6350cb6
5、https://zhang759740844.github.io/2017/07/05/Swift%E5%92%8COC%E7%9A%84%E6%B7%B7%E7%BC%96%E5%AE%9E%E8%B7%B5/
6、http://www.php-master.com/post/151913.html
7、https://www.jianshu.com/p/34bf481d5c13
8、https://www.jianshu.com/p/b763b65005bd
9、https://gysxl.github.io/2017/11/03/%E5%9F%BA%E4%BA%8EXCUITest%E8%BF%9B%E8%A1%8C%E7%9A%84iOSMonkey%E6%B5%8B%E8%AF%95/
10、http://www.php-master.com/post/151913.html
11、https://moto0421.iteye.com/blog/1570876
12、https://juejin.im/entry/58eddde3570c350057f2b975

Swift 与 OC 互相调用

阅读数 2833

oc调用swift

阅读数 1594

没有更多推荐了,返回首页