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代码)。

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

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代码)。

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

最新一些学妹问起,所以抽点时间来写的,适合入门级别的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.
}


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代码)。

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

之前在开发是遇到了在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.如此则大功告成!

2016-07-21 02:13:54 wj748499404 阅读数 4193
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

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

    2904 人正在学习 去看看 任苹蜻
swift中使用OC类的方法:
1.当新建OC的类时-->Create Bridging Header

2.桥接文件
当我们开发Swift中 使用OC的类 需要在桥接文件中导入相应的OC的类

3.直接在swift中调用

  let instance = OCOnceToken.shareTools()
        
        print("\(instance)")

注意事项:当新建OC的类时-->Create 没有点这个,就需要自己创建桥接文件: -->OC中的点H文件,新建好了之后在工程的设置里面修改桥接文件: 注意格式: 项目名称/桥接文件名称(含.h后缀)

OC文件中使用swift方法;
步骤和注意事项和上面一样:(其余如下)

1.在swift里面
class SwiftToOc: NSObject {
    static let swiftOc: SwiftToOc = SwiftToOc()    
}

2.在OC中调用swift方法
//先导入swift的头文件,格式: #import "项目名-Swift.h"
 SwiftToOc *SW = [SwiftToOc swiftOc];
    
    NSLog(@"%@",SW);

  - 注意 如果当前的项目名中 有数字和中文还有‘-’ 会导入不成功

  - 如果当前使用有数字和中文还有‘-’ 可以 修改product name


注意事项:当新建OC的类时-->Create 没有点这个,就需要自己创建桥接文件: -->OC中的点H文件,新建好了之后在工程的设置里面修改桥接文件: 注意格式: 项目名称/桥接文件名称(含.h后缀)





2015-11-14 11:30:12 Xiao_Long_Li 阅读数 1594
  • iOS/Swift/OC/Objective-C/Xcode/0基础/入门

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

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

OC调用Swift


如果你想在Objective-C工程中,嵌入Swift文件,实现OC调用Swift,那么这篇文章就能帮助你,由于本人最近在开发Swift项目,所以实现过OC调用Swift,在这过程中遇到过一些瓶颈,特此,将此文奉上,供大家参考。

OC调用Swift文件,需要创建桥接头文件,这个文件是当你在OC开发环境中创建Swift文件时由Xcode生成,该桥接头文件的命名是:<工程名>-Bridging-Header.h,它的作用是实现OC和Swift文件混编,并且如果我们想在当前OC类中调用Swift文件,必须在当前OC类中包含头文件,它的命名是:<工程名>-Swift.h,该头文件是由Xcode本身去维护,当我们点击进入到该头文件时,会看到Swift文件被编译成了OC封装的接口。

下面让我们来通过一个小Demo,进一步了解如何实现OC调用Swift。


第一步:创建OC工程

启动Xcode 7.1,然后单击File→New→Project菜单,在打开的Choose atemplate for your new project界面中选择“iOS →Application→Single View Application”工程模板(如下图所示)。


选中Single View Application单击“Next”,会出现如下图所示



这里我们将工程名命名为OCCallSwift,单击“Next”,就会出现下图所示的界面


单击“Create”,这时我们的OC工程就创建好了。

接下来我们创建一个OC的类,类名为OCViewController,具体怎么创建就不详细说了。


第二步:在OC工程中添加Swift文件


在当前OC工程中,创建Swift文件,如下图所示:


选中Cocoa Touch Class,点击“Next”,此时会跳到下图:


这里我们将Swift文件命名为SwiftViewController,将Language设置为Swift,单击“Next”,跳到下图:


这时单击“Creat”,就会弹出“Would you like to configure an Objective-C bridging header?”,如下图所示


单击“Create Bridging Header”,这时我们就在OC工程中创建好了一个Swift文件,如下图所示



第三步:实现OC调用Swift

这里我们就简单实现一下在OC类中跳转到Swift文件中

1)在OC类中包含头文件

#import <OCCallSwift-Swift.h>,命名规则为:<工程名>-Swift.h,如下图所示


2)在OC类中调用Swift文件,跟OC类调用OC类实现方式一样,如下图所示:



这样我们就实现了OC调用Swift。


友情提示:1.以上的代码是在Xcode7.1中实现,并且是新工程;

2.必须创建桥接头文件(“Create Bridging Header);

3.必须在调用Swift文件的OC类中包含如下头文件:<工程名>-Swift.h

4.如果以上条件全部符合,但是你在一个老的OC应用中调用Swift,有可能出现下面情况'<工程名>.Swift' file not found,这时你就应该在Xcode中的Build Setting中找到"Defines module",将其改为Yes


特别说明:1. 以上Swift文件均指Swift类;

  2. Swift语言为Swift2.0版本。


著作权声明:本文为原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢

Swift 与 OC 互相调用

阅读数 2833

oc可以调用swift

阅读数 329

OC工程调用Swift方法

阅读数 9103

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