iOS 开发之JS与Native交互

最近项目中用到了JS与OC交互的,所以我就来讲一下JS与OC交互的详细过程,以及在做项目的时候遇到的问题,跟大家分享一下。

1:关于交互实现方式的选择。

网上讨论比较多的有一个第三方库WebViewJavascriptBridge,个人不建议用,因为本身我们在做H5交互的时候就是给前端增加了工作量,而这种处理方式就需要前端要配置两套代码,一套给安卓,一套给iOS,而且不利于调试。所以我最后选择用系统的JavaScriptCore框架,JavaScriptzCore内部有五个框架,分别是:

#import"JSContext.h",

#import"JSValue.h",

#import"JSManagedValue.h",

#import"JSVirtualMachine.h",

#import"JSExport.h"

本文只讲常用的JSContext和JSValue,JSExport这三个类。

(1):JSContext为JavaScript提供运行环境,通过-
(JSValue *)evaluateScript:(NSString
*)script;这个方法就可以执行一段JS的脚本代码,具体使用方法如下:

NSString *alertJS=@"alert(‘test
js OC‘)";//准备执行的js代码

[self.jsContextevaluateScript:alertJS];//通过oc方法调用js的alert

(2):JSValue是JavaScript和Native之间互换的桥梁,它提供了多种方法可以方便地把JavaScript数据类型转换成Objective-C,或者是转换过去。

Objective-c    JavaScript

nil              undefined         //对应的参数转换关系

NSNull           null

NSString         string

NSNumber         number,boolean

NSDictionary     Object object

NSArray          Array object

NSDate           Date object

NSBlock          Function object

id               Wrapper object

Class            Constructor object

方法的转换举例:

1‘)self.jsContext[@"test1"]
= ^() {

NSArray *args = [JSContextcurrentArguments];

for (id
obj in args) {

NSLog(@"测试:%@",obj);

}

};

2’)

//调用JS的方法并给JS传参数

JSValue *jsFunc2 =self.jsContext[@"getId"];//getId是JS里面的方法

PersonalSetting *s =[[PersonalSettingalloc]init];

BOOL session_nil = s.session
== nil || [s.session isEqualToString:@""];

BOOL addrID_nil = s.addr ==nil||[s.addrisEqualToString:@""];

if (addrID_nil ==YES)
{

s.addr_id =@"undefined";

}

if (session_nil ==YES){

s.session =@"undefined";

}

[jsFunc2callWithArguments:@[@{@"session":
s.session,@"addr":s.addr}]];

(3):异常处理

Objective-C的异常会在运行时被Xcode捕获,而在JSContext中执行的JavaScript如果出现异常,只会被JSContext捕获并存储在exception属性上,而不会向外抛出。时时刻刻检查JSContext对象的exception是否不为nil显然是不合适,更合理的方式是给JSContext对象设置exceptionHandler,它接受的是^(JSContext
*context, JSValue *exceptionValue)形式的Block。其默认值就是将传入的exceptionValue赋给传入的context的exception属性:

/******2.关联打印异常,由于JS的异常信息是不会在OC中被直接打印的,所以我们在这里添加打印异常信息*******/

_jsContext.exceptionHandler
= ^(JSContext *context,JSValue
*exceptionValue) {context.exception
= exceptionValue;NSLog(@"异常信息:%@",
exceptionValue);};

(4):开发步骤

1’:#import<JavaScriptCore/JavaScriptCore.h>
 #import<UIKit/UIKit.h>

2‘:

@interface H5DetailVC ()<UIWebViewDelegate>

@property (nonatomic,strong)
UIWebView *webView;

@property (nonatomic,strong)
JSContext *jsContext;

@property (nonatomic,strong)
OCModel   *jsocModel;

@end

3’:- (UIWebView
*)webView{

if (_webView
== nil) {

_webView = [[UIWebViewalloc]initWithFrame:CGRectMake(0,0,[UIScreenmainScreen].bounds.size.width,[UIScreenmainScreen].bounds.size.height-64)];

_webView.scalesPageToFit
= YES;

_webView.scrollView.showsVerticalScrollIndicator=NO;

_webView.scrollView.showsHorizontalScrollIndicator=NO;

_webView.scrollView.bounces=NO;

_webView.backgroundColor
= f6f6f6Color;

}return_webView;}

4‘:

-
(void)initOCModel{

self.jsContext=[[JSContextalloc]init];

self.jsocModel
=[[OCModelalloc]init];

//传导航控制器

self.jsocModel.navigationContro=(NavigationViewController
*)self.navigationController;

//传换地址的参数

self.jsocModel.ptOrderID=self.ptOrderID;

self.jsocModel.regionID=self.regionID;

self.jsocModel.title=self.shareTitle;

self.jsocModel.content=self.content;

self.jsocModel.imageURL=self.imageURL;

self.jsocModel.shareURL=self.shareURL;

//回调

__weaktypeof(self)weakSelf
= self;

self.jsocModel.block
= ^(CheckOrderControllerCellInfo *cellInfo,NSString
*tuan_id,NSString *ptOrderID){

CheckOrderController
*vc=[CheckOrderControllercreateViewController:cellInfo];

vc.tuan=tuan_id;

vc.order=ptOrderID;

__strongtypeof(weakSelf)strongSelf=weakSelf;

dispatch_async(dispatch_get_main_queue(),
^{

[strongSelf.navigationControllerpushViewController:vcanimated:YES];

});

};

}

- (void)dealloc{

NSLog(@"回收");

}

- (void)loadRequest{

NSURL *url = [NSURLURLWithString:self.h5Url];

NSURLRequest
*request = [NSURLRequestrequestWithURL:url];

[_webViewloadRequest:request];

}

- (void)backVC{

if
([_webViewcanGoBack])
{

[_webViewgoBack];

}else{

[self.navigationControllerpopViewControllerAnimated:YES];

}

}

- (void)setID{

JSValue *jsFunc2 =self.jsContext[@"getId"];

PersonalSetting
*s =[[PersonalSettingalloc]init];

BOOL session_nil = s.session
==nil || [s.session isEqualToString:@""];

BOOL
addrID_nil = s.addr ==nil||[s.addr isEqualToString:@""];

if
(addrID_nil == YES) {

s.addr =@"undefined";

}

if
(session_nil == YES){

s.session
= @"undefined";

}

[jsFunc2callWithArguments:@[@{@"session":
s.session,@"addr":s.addr_id}]];

}

#pragma mark - UIWebViewDelegate

- (void)webViewDidFinishLoad:(UIWebView
*)webView{

/*************************************** 1.初始化content**********************************/

_jsContext = [webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

/******2.关联打印异常,由于JS的异常信息是不会在OC中被直接打印的,所以我们在这里添加打印异常信息*******/

_jsContext.exceptionHandler
= ^(JSContext *context,JSValue
*exceptionValue) {

context.exception
= exceptionValue;

NSLog(@"异常信息:%@",
exceptionValue);

};

/***************************************3.初始化JSOCModel********************************/

self.jsContext[@"OCModel"]
= self.jsocModel;

self.jsocModel.jsContext
  = self.jsContext;

self.jsocModel.webView
    = self.webView;

//    NSString *[email protected]"alert(‘test js
OC‘)"; //准备执行的js代码

//    [self.jsContext evaluateScript:alertJS];//通过oc方法调用js的alert

}

- (void)webView:(UIWebView
*)webView didFailLoadWithError:(NSError *)error{

[MBProgressHUDshowError:@"加载失败"];

}

- (BOOL)webView:(UIWebView
*)webView shouldStartLoadWithRequest:(NSURLRequest *)requests navigationType:(UIWebViewNavigationType)navigationType{

returnYES;

}

   (6):OCMode内部的实现

#import <Foundation/Foundation.h>

#import <JavaScriptCore/JavaScriptCore.h>

#import <UIKit/UIKit.h>

typedef void(^pushCheckOrderVCBlock)(CheckOrderControllerCellInfo *cellInfo,NSString *tuan_id,NSString
*ptOrderID);

@protocol JavaScriptObjectiveCDelegate <JSExport>

//跳转到登录页

- (void)pushToLoginViewController;

//获得ID

- (void)getiOSID;

//跳转到地址选择页

- (void)pushToChooseAddressVCWithParams:(NSDictionary *)params;

//分享团链接

- (void)shareTuanMethod;

//跳转到结算页

- (void)pushToCheckOrderVCWithDictonry:(NSDictionary *)params Dictionry2:(NSDictionary *)param2;

//跳转到首页的方法

- (void)pushToRootVC;

//跳转到五个人头页面

- (void)pushToFightGroupDetailVCWithPtOrderID:(NSString *)ptOrderID;

//跳转到店铺的方法

- (void)pushToShopVCWithShopID:(NSString *)shopID;

//分享红包页面

- (void)shareRedPaper;

@end

@interface OCModel :NSObject<JavaScriptObjectiveCDelegate>

@property (nonatomic,copy)pushCheckOrderVCBlock block;

@property (nonatomic,weak)JSContext *jsContext;

@property (nonatomic,weak)UIWebView *webView;

//分享的参数

@property (nonatomic,strong)NSString *title;

@property (nonatomic,strong)NSString *content;

@property (nonatomic,strong)NSString *imageURL;

@property (nonatomic,strong)NSString *shareURL;

//换地址参数

@property (nonatomic,strong)NSString *ptOrderID;

@property (nonatomic,strong)NSString *regionID;

@property (nonatomic,strong)NavigationViewController
*navigationContro;

@end

//

//  OCModel.m

//  XXX

//

//  Created by lirong on 16/4/20.

//  Copyright ? 2016年 daming. All rights reserved.

//

#import "OCModel.h"

#import "ShareView.h"

#import "SubjectShopController.h"

@implementation OCModel

#pragma mark -登录

- (void)pushToLoginViewController{

LoginViewController *vc=[[LoginViewControlleralloc]init];

[self.navigationContro pushViewController:vcanimated:YES];

}

- (void)getiOSID{

JSValue *jsFunc2 =
self.jsContext[@"getId"];

PersonalSetting *s =[[PersonalSettingalloc]init];

BOOL session_nil = s.session ==nil || [s.session isEqualToString:@""];

BOOL addrID_nil = s.addr ==nil||[s.addr isEqualToString:@""];

if (addrID_nil ==
YES) {

s.addr = @"undefined";

}

if (session_nil ==
YES){

s.session =
@"undefined";

}

[jsFunc2 callWithArguments:@[@{@"session": s.session,@"addr":s.addr}]];

}

#pragma mark -选地址

- (void)pushToChooseAddressVCWithParams:(NSDictionary *)params{

PersonalSetting *s=[PersonalSettinggetInstance];

s.send = [params
objectForKey:@"send"];

s.singleOrGroup = [params
objectForKey:@"type"];//"TUAN" "SINGLE"

NSString *Order=[params
objectForKey:@"order"];

NSString *tuan=[params
objectForKey:@"tuan"];

s.tuan = tuan;

LocateAndChooseAddressControllerParam *param = [[LocateAndChooseAddressControllerParamalloc]init];

param.from =@"去结算页";

param.pt_order_id = Order;

LocateAndChooseAddressController *vc= [LocateAndChooseAddressControllercreateViewController:param];

__weak
typeof(self)weakSelf=self;

dispatch_async(dispatch_get_main_queue(), ^{

[weakSelf.navigationContro
pushViewController:vc animated:YES];

});

//    [self.navigationContro pushViewController:vc animated:YES];

}

#pragma mark -分享

- (void)shareTuanMethod{

[TalkingDatatrackEvent:@"呼唤小伙伴"];

PersonalSetting *s=[PersonalSettinggetInstance];

s.paySuccess =
YES;

ShareView *shareV=[ShareViewdefaultShareView];

NSData *data=[NSDatadataWithContentsOfURL:[NSURLURLWithString:self.imageURL]];

UIImage *image=[UIImageimageWithData:data];

[shareV setShareContentWithTitle:self.title content:self.content title2:@"" content2:@"" shareImage:imageshareURL:self.shareURL];

[shareV show];

[shareV setShareViewBlock:^(BOOL isSuccess) {

if (isSuccess) {

DLog(@"分享成功");

}else {

DLog(@"分享失败");

}

}];

s.paySuccess =
NO;

}

#pragma mark -checkout成功去结算页

- (void)pushToCheckOrderVCWithDictonry:(NSDictionary *)params Dictionry2:(NSDictionary *)param2{

DLog(@"param2:%@",param2);

DLog(@"params:%@",params);

PersonalSetting *s=[PersonalSettinggetInstance];

s.send = [param2
objectForKey:@"send"];

s.singleOrGroup = [param2
objectForKey:@"type"];

NSString *Order=[param2
objectForKey:@"order"];

CheckOrderControllerCellInfo*cellInfo=[[CheckOrderControllerCellInfoalloc]init];

NSString *limit=[[params
objectForKey:@"limit"]
stringValue];

//购物车

NSMutableArray *cart=[params
objectForKey:@"cart"];

NSDictionary *cartDict=[[NSDictionaryalloc]init];

NSMutableArray *image=[[NSMutableArrayalloc]init];//商品图片数组

NSString *price=@"";

NSString *status=@"";

NSString *title1=@"";

NSString *tuan_id=@"";

NSString *type=@"";

NSString *shopName=@"";

if (cart.count>0) {

cartDict=[cart objectAtIndex:0];

image=[cartDict objectForKey:@"image"];

price=[cartDict objectForKey:@"price"];

status=[cartDict objectForKey:@"status"];

title1=[cartDict objectForKey:@"title1"];

tuan=[cartDict objectForKey:@"tuan"];

type=[cartDict objectForKey:@"type"];

shopName=[cartDict objectForKey:@"shopName"];

}

NSString *cart_title=[params
objectForKey:@"cart_title"];

//    NSString *coupon=[params objectForKey:@"coupon"];

//    NSString *coupon_disc=[params objectForKey:@"coupon_disc"];

NSMutableArray *coupon_list=[params
objectForKey:@"coupon_list"];//优惠券

NSString *due=[params
objectForKey:@"due"];

NSString *inventory=[[params
objectForKey:@"inventory"]
stringValue];

NSString *cre = [params
objectForKey:@"cre"];

NSString *useCre = [params
objectForKey:@"use_cre"];

//给结算页传值

cellInfo.title=title1;

cellInfo.credit = credit;

cellInfo.use_credit = useCredit;

cellInfo.groupNumber=[NSStringstringWithFormat:@"%@",type];

cellInfo.price=price;

cellInfo.due=due;

cellInfo.cart_title = cart_title;

cellInfo.couponList = [[NSMutableArrayalloc]init];

for (int i=0;i<coupon_list.count;i++){

SkuCheckoutModel *model=[[CheckoutModelalloc]init];

model.id            = coupon_list[i][@"id"];

model.cash          = coupon_list[i][@"cash"];

model.valid         = coupon_list[i][@"valid"];

model.coupon_status = coupon_list[i][@"coupon_status"];

model.msg1          = coupon_list[i][@"msg1"];

model.msg2          = coupon_list[i][@"msg2"];

model.threshold     = coupon_list[i][@"threshold"];

[cellInfo.couponList
addObject:model];//优惠券

}

if (buy_limit !=nil&&![buy isEqualToString:@""]) {

cellInfo.limitNum=[buy intValue];

}

if (inventory !=nil&&![inventoryisEqualToString:@""]) {

cellInfo.stockQuantity=[inventory
intValue];

}

cellInfo.shopName=shopName;

if (_block) {

_block(cellInfo,tuan_id,ptOrderID);

}

}

#pragma mark -回首页

- (void)pushToRootVC{

[self.navigationContropopToRootViewControllerAnimated:YES];

}

#pragma mark -跳转到XXX页面

- (void)pushToFightGroupDetailVCWithPtOrderID:(NSString *)ptOrderID{

DetailViewController *vc=[[DetailViewController alloc]init];

vc.order=ptOrderID;

__weak
typeof(self)weakSelf=self;

dispatch_async(dispatch_get_main_queue(), ^{

[weakSelf.navigationContro
pushViewController:vc animated:YES];

});

//    [self.navigationContro pushViewController:vc animated:YES];

}

#pragma mark -跳转到店铺页面

- (void)pushToShopVCWithShopID:(NSString *)shopID{

SubjectShopController *vc=[[SubjectShopControlleralloc]init];

vc.supplier_id=shopID;

__weak
typeof(self)weakSelf=self;

dispatch_async(dispatch_get_main_queue(), ^{

[weakSelf.navigationContro
pushViewController:vc animated:YES];

});

//    [self.navigationContro pushViewController:vc animated:YES];

}

- (void)showAlert:(NSString *)title msg:(NSString *)msg {

dispatch_async(dispatch_get_main_queue(), ^{

UIAlertView *a = [[UIAlertViewalloc]initWithTitle:titlemessage:msgdelegate:nilcancelButtonTitle:@"Ok"otherButtonTitles:nil,nil];

[a show];

});

}

#pragma mark - 确认收货发红包

- (void)shareRedPaper{

PersonalSetting *s=[PersonalSettinggetInstance];

s.paySuccess =
YES;

ShareView *shareV=[ShareViewdefaultShareView];

//    NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:self.imageURL]];

//    UIImage *image=[UIImage imageWithData:data];

[shareV setShareContentWithTitle:self.titlecontent:self.contenttitle2:@""content2:@""shareImage:nilshareURL:self.shareURL];

[shareV show];

[shareV setShareViewBlock:^(BOOL isSuccess) {

if (isSuccess) {

DLog(@"分享成功");

}else {

DLog(@"分享失败");

}

}];

s.paySuccess =
NO;

}

@end

(7):webView 多次push页面会造成crash,一般都是crash在webView的线程WebThread里。

这种情况是因为主线程被卡住了。主线程被卡住是非常常见的场景,具体表现就是程序不响应任何的UI交互。所以我们在webView里面进行push操作的时候,一定要在主线程里面进行。

__strongtypeof(weakSelf)strongSelf=weakSelf;

dispatch_async(dispatch_get_main_queue(),
^{

[strongSelf.navigationControllerpushViewController:vcanimated:YES];

});

4:JS端的写法:(举例说明)

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

</head>

<body>

<script>

var isLogin =
false;

var session_id ;

var addr_id =
"";

var device;

function _isIoS(){

var ua = navigator.userAgent.toLowerCase();

if(ua.match(/iPhone\sOS/i) ==
‘iphone os‘){

return
true;

}else{

return
false;

}

}

function _isAndroid(){

var ua = navigator.userAgent.toLowerCase();

var msgss = navigator.userAgent

if(ua.match(/Android/i) ==
‘android‘){

return
true;

}else{

return
false;

}

}

if(_isAndroid()){

device = ‘android‘;

}else
if(_isIoS()){

device = ‘ios‘;

}

function toLogin(){

if(device==‘android‘){

PtUbossJsInterface.toLogin()

}else
if(device == ‘ios‘){

OCModel.pushToLoginViewController()

}else{

}

}

function getLoginSession_id(){

if(device==‘android‘){

PtUbossJsInterface.getLoginSession_id(setIsLogin);

}else
if(device == ‘ios‘){

OCModel.getSessionID()

}else{

}

}

function toAddrList(){

if(device==‘android‘){

PtUbossJsInterface.toAddrList()

}else
if(device == ‘ios‘){

OCModel.pushToChooseAddressVCWithParams({})

}else{

}

}

function getAddrId(){

if(device==‘android‘){

PtUbossJsInterface.getAddrId(setAddrId)

}else
if(device == ‘ios‘){

OCModel.getAddressID()

}else{

}

}

function shareTuanLink(){

if(device==‘android‘){

PtUbossJsInterface.shareTuanLink(‘c‘,‘d‘,‘d‘,‘dfs‘)

}else
if(device == ‘ios‘){

OCModel.shareTuanMethodShareURLTitleContentImageURL(‘a‘,‘b‘,‘c‘,‘d‘)

}else{

}

}

function toPtCheckout(){

if(device==‘android‘){

PtUbossJsInterface.toPtCheckout()

}else
if(device == ‘ios‘){

OCModel.pushToCheckOrderVCWithDictonry()

}else{

}

}

function toFirstActivity(){

if(device==‘android‘){

PtUbossJsInterface.toFirstActivity()

}else
if(device == ‘ios‘){

OCModel.pushToRootVC()

}else{

}

}

function toShop(){

if(device==‘android‘){

PtUbossJsInterface.toShop()

}else
if(device == ‘ios‘){

OCModel.pushToShopVCWithShopID(‘shop_id‘)

}else{

}

}

function toPtDetail(){

if(device==‘android‘){

PtUbossJsInterface.toPtDetail(‘pt11604221104zmlow3‘);

}else
if(device == ‘ios‘){

OCModel.pushToFightGroupDetailVCWithPtOrderID(‘pt11604221104zmlow3‘);

}else{

}

}

</script>

<p id="id_device">当前的手机机型</p>

<div>

<article
id="id_login">登入状态</article>

<button onclick="toLogin()">到登入页</button>

<button
onclick="getLoginSession_id()">获取登入状态</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article id="id_addr_id">当前选中的地址id</article>

<button onclick="toAddrList()">跳转到地址选择页面</button>

<button onclick="getAddrId()">获取当前选中地址的id</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article></article>

<button onclick="shareTuanLink()">分享团链接的方法</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article></article>

<button onclick="toPtCheckout()">到结算页的方法</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article></article>

<button
onclick="toFirstActivity()">跳回首页的方法</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article></article>

<button onclick="toShop()">跳转到店铺的方法</button>

</div>

<br>

<!--**********************************************************************-->

<div>

<article></article>

<button onclick="toPtDetail()">到详情页的方法</button>

</div>

<br>

<!--**********************************************************************-->

<script>

function setIsLogin(s){

session_id = s;

alert(s);

if(session_id){

document.getElementById(‘id_login‘).innerHTML =‘用户已登入‘+session_id;

}else{

document.getElementById(‘id_login‘).innerHTML =‘用户未登入‘

}

}

document.getElementById(‘id_device‘).innerHTML="当前设备是"+device;

if(isLogin){

document.getElementById(‘id_login‘).innerHTML =‘用户已登入‘

}else{

document.getElementById(‘id_login‘).innerHTML =‘用户未登入‘

}

function setAddrId(id){

addr_id = id;

document.getElementById(‘id_addr_id‘).innerHTML = addr_id;

}

</script>

</body>

</html>

时间: 2024-10-08 15:16:50

iOS 开发之JS与Native交互的相关文章

iOS开发之WKWebView简单使用和常用使用场景

iOS开发之 WKWebVeiw使用 想用UIWebVeiw做的,但是突然想起来在iOS8中出了一个新的WKWebView,算是UIWebVeiw的升级版.本着对新事物的好奇,就上网查了一下,但是找了好多个都没说的多了详细,于是就问谷歌,找文档,看看使用方法,试用了一下,果然不错,记录下来,大家分享! WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷

李洪强IOS开发之iOS好项目收集

李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501018 JHChainableAnimations 可读性好使用方便的动画库,语法类似与Masonry,使用链式编程 20150506 awesome-ios-chart iOS平台下的各种图表组件 20150513 DevArticles iOS Animation 主流炫酷动画框架(特效)收集整

iOS开发之MVVM在项目中的应用

今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦~). 由于本人项目经验有限,关于架构设计方面的东西理解有限,我个人对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架~在学校的时候用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人了. 说到架构设计和团队

iOS 开发之Target-action模式

Target-action:目标-动作模式,它贯穿于iOS开发始终.但是对于初学者来说,还是被这种模式搞得一头雾水. 其实Target-action模式很简单,就是当某个事件发生时,调用那个对象中的那个方法.如:按下按钮时,调用Controller里边的click方法.“那个对象”就是Target,“那个方法”就是Action,及Controller是Targer,click方法是action. 一般Target都是Controller,而Action有它自己固有的格式:-(IBAction)c

李洪强iOS开发之iOS好文章收集

李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 nginx 和 rtmp 插件搭建视频直播和点播服务器 2015-05-12 20:13:00 iOS9适配技巧 图iOS9适配新技巧 2015-09-29 09:01 TextKit分页效果 图文混排 2015年6月1日 iPhone 6 / 6 Plus 设计·适配方案 屏幕适配 2014-11-2

【IOS开发之Objective-C】协议和代理

在现实生活中我们存在各种各样的协议,但是都有一个共同点,就是拟定的协议,就要遵守,不遵守就是违约.在OC中也有协议这一个概念而且和我们现实生活中的协议的特点是类似的.有时我们自己想做什么事,但是现在没这个能力自己去做,亲力亲为,我们就需要找代理来帮我们做了.那么在OC中也有代理这个概念.下面就简单的说说OC中的协议和代理. 一.协议 在<[IOS开发之Objective-C]对象的交互>中实现了一种对象的交互的方式.在OC中还有其他方式,比如说协议,在OC中用协议来规范接口,是实现对象之间的交

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

iOS开发之CocoaPods的使用

透明色:00ff00ff //设置柱状图的颜色                ColorSet cs = new ColorSet();                cs.Id = "colorset1"; #region 设置柱状图的颜色 待开发                    string strColor = oYAXIS.Color;                    switch (strColor)                    {