-
Notifications
You must be signed in to change notification settings - Fork 1
Home
JSAUIKitCocoa是为使用JavaScript混合Objective-C开发iOS应用提供的MVC框架,以及为部分原生UI组件(如UIView)提供JavaScript快速初始化支持。
我们将用MMVVC模式创建这样一个应用界面
用户进入登录页面时,显示最后一次登录的用户信息,用户修改用户名后,头像中的名称显示当前用户名(真实场景应该会改变头像图片)
$class("app.UserManagerModel",{
$static:{
lastloginUser:function(){
return {
username:"UserA",
password:"password"
}
}
}
});
lastloginUser方法返回最后一次登录的用户信息,即Domain-value Object。
$class("app.AvatarView",{
$init : function(param){
this.textView = $new("UILabel","initWithJSAParam:",{
fontSize:12,
textColor:"#FFFFFF",
textAlignment:"center"
});
var avatarView = $new("MyRelativeLayout","initWithJSAParam:",Object.assign(param,{
backgroundColor:"#03A9F4",
subviews:[
{
view:this.textView,
leftPos:5,
topPos:5,
rightPos:5,
bottomPos:5,
}
]
}));
//这里是一个小技巧,将一个非OC代理对象转换为OC代理对象,以便该对象传递到OC系统时转换为OC对象
this.$this = avatarView.$this;
},
setName:function(name){
name = name.trim();
if(name == ""){
name = "Unknown";
}
this.textView.invoke("setText:",name);
}
});
用户头像是一个ModelView,即和业务逻辑相关的View,这个View将显示用户头像,并可以重新设置用户名(setName方法),setName方法在此DEMO实现中只是将头像中的文本设置为新的名字,真实业务场景可以调用Model层方法获取用户名对应的图片,然后修改头像图片。相比ViewMode的Data-Bind,ModelView可以包含更加复杂的显示转换逻辑。同时这个ModelView可以复用到任何需要展示用户头像的地方。
使用OC编写ModelView
如果这个ModelView的显示逻辑更为复杂,如处理复杂动画显示,则这个ModelView可直接使用OC编写,即编写一个UIView的继承类,在这个例子中,AvatarView实际是一个MyRelativeLayout(MyLayout框架中的相对布局UIView)对象,AvatarView使用JS脚本编写显示业务逻辑,在MyRelativeLayout中放入了一个UILabel以显示用户名文本。
ModelView中使用的OC原生类,如MyRelativeLayout、UILabel,因为其与业务逻辑无关,则可视为View层组件。
$class("app.LoginView",{
$init : function(lastloginUser){
this.avatarView = new app.AvatarView({
width:80,height:80
});
this.avatarView.setName(lastloginUser.username);
this.userNameInput = $new("UITextField","initWithJSAParam:",{
width:200,height:30,borderStyle:"RoundedRect",
placeholder:"用户名",
text:lastloginUser.username,
onEditingDidEnd:function(view){
jsa.cocoa.UIResponder.fromNative(view).dispatch("onEditingDidEnd",null,null);
}
});
this.passwordInput = $new("UITextField","initWithJSAParam:",{
width:200,height:30,borderStyle:"RoundedRect",secureTextEntry : true,
placeholder:"密码",
text:lastloginUser.password,
});
var loginView = $new("MyRelativeLayout","initWithJSAParam:",{
subviews:[
{
id : "avatar",
view:this.avatarView,
topPos :{value : "safeAreaMargin",offset : 20},
centerXPos : 0,
},
{
id:"username",
view:this.userNameInput,
topPos :{id : "avatar",pos : "bottomPos",offset : 10,},
centerXPos : 0,
},
{
id:"password",
view:this.passwordInput,
topPos :{id : "username",pos : "bottomPos",offset : 10,},
centerXPos : 0,
},{
view:jsa.cocoa.UIButton.button({
type:"System",
width:50,
height:30,
title:"登录",
onClick:function(view){
jsa.cocoa.UIResponder.fromNative(view).dispatch("onLoginClicked",null,null);
}
}),
topPos :{id : "password",pos : "bottomPos",offset : 10,},
centerXPos : 0,
}
]
});
jsa.cocoa.UIResponder.fromNative(loginView.$this).setObserver(this);
this.$this = loginView.$this;
},
onEditingDidEnd:function(){
//在用户名输入结束后,将新的用户名更新到avatarView
var username = this.userNameInput.invoke("text");
this.avatarView.setName(username);
},
onLoginClicked:function(){
//当点击登录按钮时,发出登录事件,并在事件对象中加入登录表单对象的值(类似于form的post)
var username = this.userNameInput.invoke("text");
var password = this.passwordInput.invoke("text");
//抛出事件,Controller可监听该事件以处理登录事件
jsa.cocoa.UIResponder.fromNative(this.$this).dispatch("onLogin",null,{
username:username,
password:password
});
}
});
LoginView即登录页面,在LoginView中使用app.AvatarView来展示用户头像,并监听UITextField组件的onEditingDidEnd事件,以动态改变登录用户名对应的用户头像。通过引入ModelView,可有效的将显示业务中的临时交互逻辑放在ModelView中,而避免将显示逻辑代码写在Controller中。
$class("app.Main",{
$extends : "jsa.cocoa.JSAUIViewController",
getView : function(viewController){
var lastloginUser = app.UserManagerModel.lastloginUser();
this.loginView = new app.LoginView(lastloginUser);
return this.loginView;
},
onLogin:function(object,userInfo){
console.log("User:"+userInfo.username+" Password:"+userInfo.password);
}
});
在将显示逻辑分离到ModelView后,Controller的职责就更加清晰了,getView方法中获得页面所需的Model数据,并用Model数据初始化页面对应的ModelView对象。
onLogin方法处理loginView视图中的登录事件。
该DEMO的可运行版本已包含在JSAUIKitCocoaDemo,JS脚本地址:https://github.com/JSAppSugar/JSAUIKitCocoa/tree/master/JSAUIKitCocoaDemo/JSApp/app