想写点东西在iPad上应该点击图片跳转链接链接哪里

IPAD要怎么才能连接电脑 IPAD连接电脑具体步骤_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
IPAD要怎么才能连接电脑 IPAD连接电脑具体步骤
&&IPAD要怎么才能连接电脑 IPAD连接电脑具体步骤
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢查看: 10407|回复: 76
论坛,对我来说,不只是一个看帖子找乐的地方,从我第一次点击登录大众论坛,它对我来说都有另外一种意义。这个意义,只有我的同事能懂,我的家人能懂。
我性别女,88年出生,来自山东内陆某城市,大学期间游学山城重庆四年,毕业后因为至亲在日照,便留在了日照。
一待就是6年,工作单位没换过、结婚生了女儿。外表若无其事而内心时刻对这个日照之小感到无奈,如果人生能重来,时光倒流回六年前,我肯定不会选择留在日照,而是去接触大城市的竞争和节奏。我想我还是平静外表下有一颗不安心的人,纵使已结婚对年。
可是,没有如果。
日子总得往前看,往好的地方看。在日照,我并没有遭遇过生活和工作上的极大不公,一个看似善良的人也学会了时时刻刻带着刺去面对一些事情,尤其是在一个长期不变的环境下长期处理着类似的事情,耐心却不比以往。庆幸的是,我问了问自己,内心告诉的是七个字“我还有爱的勇气”。
城市小不好吗?大城市车辆限号,人满为患。日照的环境算是好的吧!!还以为你要夸夸日照呢。&
工作单位没换过?为何?是金会发光的,时光不能倒流,职业可以选择吧。努力,祝福你!&
听楼主讲故事
团结友爱互助爱家, 融入和谐的大家庭
来自手机客户端
人所有的不甘,说到底小部分是内心的,行动跟不上思想有什么用?还不如认命。多部分还是因为外在的因素,因为比较,所以不甘。总是在初心与还是随波逐流之间挣扎,其实,无需想太多,都是给自己套了枷锁。
现在还年轻!!!加油,小城市也可以有大作为!
板凳瓜子苏磊茶,前排就坐,听故事……
心中有太多的无奈
生活还是美好的,至少我们过着比上不足,比下有余的生活,看看那些为了工作四处奔波的人,我们应该庆幸我们有份能解决温饱的工作,看看那些大龄单身急有四处冒烟的人,我们还有个幸福的家庭,有爱我们的家人、孩子,相比同学,朋友,是不是自己还算不错,并不是打击那些目前过的不好的人,只是说我们自己应该找到平衡点,调整好心态,知足常乐。
来自手机客户端
一个靠关系的小城
日照很小,在我心里很大.
从黄海一路一直到海边灯塔,海边的每颗冬青树我都知道它的年龄生日.灯塔十几年前啥样,三十年前啥样都记忆深刻.跟幻灯片一样,历历在目
日照不错.漂泊在外的都觉得自己家乡好
小小D人 发表于
一个靠关系的小城
可以这么说,城市越小,找关系的可能就越大。
如在村里,都是认识的;在镇上,认识的很多,在一个小城,那也不少,三转两转就认识了。
所以说,这样的环境,法制不如关系,中国的一个桎梏就是关系,只有在100万人口以上的城市,才有可能摆脱关系,靠规则制度来运行,这才是我们向往的。
关系其实是破坏规则,破坏公平的社会环境,抵制关系,从,,,,,
本帖最后由 猫腻雪 于
14:00 编辑
记得我初中毕业后,那是我第一次来日照。第一次自己做上长途大巴车,来日照找姐姐。一路上不停通过短信告知姐姐我到了哪里,不敢睡,随时往车窗外张望寻找能定位定点的路牌、广告牌,那个时候我不认识“莒”,通过电话告诉姐姐“我到上面是个草字头,下面是个吕,这个地方了”。
当时,我与姐姐租住在石臼某小区,友谊商店、海纳商城、利群超市是我们经常去的地方,夏天的时候还会步行去灯塔散步,找个地方坐下来,把鞋脱掉撩海水玩。
回到老家,爸爸问我日照有什么不一样,不知道怎么表达的我只说了三个字“路很宽”。
后来,我又趁着暑假时光来回了几趟日照。
来了之后其实也没有什么见识,多数去了石臼那边的创新蛤蜊小抓鸡去吃饭,去清华川味菜馆(应该是这个名字)去吃饭,认识了几个姐姐的同事。
那个时候,觉得去友谊商店、海纳商城买衣服很洋气,到了上学后还会有点骄傲的说是从日照买的。
总之,那时候日照是大的,比现在大很多。
南城决 发表于
人所有的不甘,说到底小部分是内心的,行动跟不上思想有什么用?还不如认命。多部分还是因为外在的因素,因 ...
忙碌起来的时候不会想
闲下来,就开始了矫情,想来想去,多了这些废话
爱静静 发表于
日照很小,在我心里很大.
从黄海一路一直到海边灯塔,海边的每颗冬青树我都知道它的年龄生日.灯塔十几年 ...
从前,日照很大
如今,却很小
那个时候,日照有多大?单纯的我以为公交车线路会多到记不住,恐怕上了车再迷路。
那个时候会觉得,日照公交车上乘客的穿着打扮都会比我们县城洋气很多,都会不一样的气质,现在想想十几岁时自己的想法真的挺可笑的……
不错,慢慢坐看。ipad版Qzone(纯swift编写)
一 app大致框架图 : (竖屏)
二 app大致框架图 : (横屏)
1 自动布局(熟悉)
2 协议(熟悉)
3 横屏和竖屏的配置(掌握)
4 细节处理
四 布局登录界面和处理业逻辑
1 自动布局效果图
2 账号和密码相关设置
&-& 2.1 账号
&-& 2.2 密码
3 创建一个登录控制器,用来处理登录模块相关业务逻辑
4 该部分需要的相关属性(通过从storyboard中拖线得到)
class XFJLoginViewController: XFJBaseViewController {
/// 登录时候转圈提示
@IBOutlet weak var activityView: UIActivityIndicatorView!
/// 登录的view
@IBOutlet weak var loginView: UIView!
/// 密码文本
@IBOutlet weak var passWordTextField: UITextField!
/// 账号文本
@IBOutlet weak var countTextField: UITextField!
//自动登录
@IBOutlet weak var autoLogin: UIButton!
//记住密码
@IBOutlet weak var remberPassword: UIButton!
5 处理账号和密码登陆的业务逻辑
&-& 5.1 isEmpty:用来判断账号和密码是否为空
&&&& 5.1.1 获取用户输入的账号和密码
&&&& 5.1.2 模拟用户登录效果(通过延迟执行达到效果)
&&&& 5.1.3 显示用户账号正在登录的提示(UIActivityIndicatorView类)
&-& 5.2 用字符串相等来判断是否输入正确
该部分业务逻辑实现代码 :
//MARK: - 判断账号和密码是否为空和密码错误
extension XFJLoginViewController {
@IBAction func loginBtnClick() { //通过对按钮拖线
//获取账号和密码
let countTF = countTextField.text
let passwordTF = passWordTextField.text
//判断内容为空是否登录
if countTF?.isEmpty == true || passwordTF?.isEmpty == true {
showError(&密码或账号不能为空&)
//为空的话,后面就没必要执行了
//判断账号和面是否正确
activityView.startAnimating()
//转圈的时候停止交互
view.userInteractionEnabled = false
//延迟执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC)), dispatch_get_main_queue(), { () -& Void in
//停止转圈
self.activityView.stopAnimating()
//允许交互
self.view.userInteractionEnabled = true
//判断账号和密码是否正确
if countTF == &123& && passwordTF == &123& {
//登录成功跳转下一个界面(这里采用修改根控制器的方法实现)
self.view.window?.rootViewController = XFJHomeViewController()
self.showError(&账号或密码错误&)
6 提示框和登录的时候账号和密码一起抖动情况
&-& 6.1 用UIAlertController这个类来达到提示用户是否登录成功
&-& 6.2 抖动效果(由于账号;密码;登录按钮;记住密码;自动登录在布局的时候是用一个UIView来作为父控制器,如果不是这样是无法达到同时抖动的效果)
该部分业务逻辑实现代码 : (考虑到该部分代码比较多,所以写在类扩展的方法中)
//MARK: - 处理登录的抖动情况
extension XFJLoginViewController {
//登录时候的抖动效果和弹框提示
private func showError (messaage : String) {
let alertControler = UIAlertController(title: &登录失败&, message: messaage, preferredStyle: .Alert)
let alertAction = UIAlertAction(title: &确认&, style: .Cancel, handler: nil)
alertControler.addAction(alertAction)
presentViewController(alertControler, animated: true, completion: nil)
//登录时候的抖动效果
let shakeAnimted = CAKeyframeAnimation(keyPath: &transform.translation.x&)
shakeAnimted.repeatCount = 3
shakeAnimted.duration = 0.1
shakeAnimted.values = [-10,0,10]
loginView.layer.addAnimation(shakeAnimted, forKey: nil)
7 自动登录和记住密码
&-& 7.1 该部分业务逻辑介绍 :
&&& 7.1.1 当记住密码被用户选中,那么自动登录也需要选中
&&& 7.1.2 当记住密码由选中到取消,那么自动登录也需要自动选中
&&& 7.1.3 当自动登录被选中,那么记住密码也需要自动选中
记住密码业务逻辑代码块 :
//MARK: - 记住密码
extension XFJLoginViewController {
@IBAction func remberBtnClick(button : UIButton) { //需要通过连线拿到
button.selected = !button.selected
if button.selected == false {
autoLogin.selected = false
自动登录业务逻辑代码块 :
//MARK: - 自动登录
extension XFJLoginViewController {
@IBAction func automaticLogin(button : UIButton) {
//需要通过连线拿到
button.selected = !button.selected
if button.selected == true {
remberPassword.selected = true
8 处理键盘上的NEXT和Down逻辑
&-& 8.1 处理思想 : 代理
&-& 8.2 业务逻辑介绍 : 1& 判断账号是否正确,如果正确点击NEXT跳入密码输入框 2& 判断密码是否正确,如果正确点击Down跳入主界面
&-& 8.3 问题 : 如何给键盘设置代理呢?
&-& 8.4 解决方法 : 在storyboard中通过连线解决(账号和密码输入框同理)
&-& 8.5 实现代理方法,在代理方法中实现相关业务逻辑
//对键盘的处理(NEXT和Down)----& 需要在storyboard中设置代理否则是下面代码是没用的
extension XFJLoginViewController : UITextFieldDelegate {
func textFieldShouldReturn(textField: UITextField) -& Bool {
textField == countTextField {
//如果判断正确,让密码键盘成为第一响应者
passWordTextField.becomeFirstResponder()
}else if passWordTextField == textField {
//如果密码相等,调用登录方法
loginBtnClick()
return true
五 处理控制器view的状态栏颜色
1 思路 : 重写系统设置状态栏的函数,将状态栏的颜色改为自己想要的,由于主界面的控制器也需要这种状态,那么我们的思想是创建一个控制器,在该类中设置状态栏样式,然后再创建一个主界面控制器,继承第一个控制.
2 用来设置状态栏的控制器
3 处理代码 :
class XFJBaseViewController: UIViewController {
//设置状态栏的样式
override func preferredStatusBarStyle() -& UIStatusBarStyle {
return .LightContent
1 创建一个继承XFJBaseViewController(主控制器也需要设置状态栏样式)的控制器.用来作为主界面控制器
2 创建左侧的工具栏(dock)是一个继承系统的UIView,用来管理底部,中间,顶部按钮
3 在XFJHomeViewController控制器中创建dock(一般是懒加载)
该部分代码 :
private lazy var dock : XFJDock = {
//创建dock
let dock = XFJDock()
//添加dock到view中
self.view.addSubview(dock)
//设置高度
dock.frame.size.height = self.view.frame.height
//设置autoresizing跟随父控件的拉伸而拉伸
dock.autoresizingMask = .FlexibleHeight
return dock
4 创建底部工具栏
&-& 4.1 注意 : 1& 代码书写位置 : XFJD 2&采用方式 : 懒加载
//懒加载底部工具栏
private lazy var bottomMenu : XFJBottom = {
//创建底部工具栏
let bottomMenu = XFJBottom()
//将创建好的底部工具条添加到view中
self.addSubview(bottomMenu)
//设置子控件跟随父控件的顶部拉伸而拉伸
bottomMenu.autoresizingMask = .FlexibleTopMargin
return bottomMenu
5 整个文件中需要用到的参数
&-& 5.1 创建一个文件用来设置整个文件需要用到的参数
&-& 5.2 该文件中需要的参数
let kDockLaceWidth : CGFloat = 270.0
let kDockProtraitWidth : CGFloat = 70.0
//item的高度
let kDockLaspaceHeight : CGFloat = 70.0
//头像横屏时候的高度
let kIconButtonLaspaceHeight : CGFloat = kIconButtonLaspaceWidth + kIconTextHeight
//头像横屏时候的宽度
let kIconButtonLaspaceWidth : CGFloat = 90.0
//头像竖屏时候的高度和宽度
let kIconProtraitWH : CGFloat = 60
//头像横屏和竖屏的时候y值一样
let kIconLpaceY : CGFloat = 40.0
//头像文字的高度
let kIconTextHeight : CGFloat = 30.0
6 处理屏幕旋转过程中dock中的各部分工具模块
&-& 6.1 通过在XFJHomeViewController重写系统的方法,在该方法中将屏幕的,通过在该方法中让屏幕的宽度和高度比较,将计较的值传入各个工具模块中
//当屏幕即将旋转的时候调用,其实并没有旋转
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
//判断当前屏幕的true还是false
let isLaspace = size.width & size.height
//设置dock的宽度
let duration = coordinator.transitionDuration()
UIView.animateWithDuration(duration) { () -& Void in
//将屏幕方向传入dock中
self.dock.roteLspaces(isLaspace)
//更新旋转后的x值
self.contentive?.frame.origin.x = self.dock.frame.width
&-& 6.2 解析 : 该方法中通过self.dock.roteLspaces(isLaspace)将判断得出的结果传入dock中,在dock中再做相应的处理
7 在XFJDock中定义一个方法,用来接收self.dock.roteLspaces(isLaspace)中的isLaspace值,同时作为参数,传到每个模块中,通过这个值来计算各个模块在屏幕不同的方向时候各模块显示的样式.
七 底部模块
1 在XFJDock类中创建XFJBottom(底部模块对象)
2 采用创建方式 : 懒加载(用到的时候再加载)
//懒加载底部工具栏
private lazy var bottomMenu : XFJBottom = {
//创建底部工具栏
let bottomMenu = XFJBottom()
//将创建好的底部工具条添加到view中
self.addSubview(bottomMenu)
//设置子控件跟随父控件的顶部拉伸而拉伸
bottomMenu.autoresizingMask = .FlexibleTopMargin
return bottomMenu
3 在XFJBottom类中布局屏幕旋转的尺寸和添加按钮
&-& 3.1 根据从XFJDock类中的方法中传入的isLaspace参数来布局底部模块的尺寸
//提供一个方法,让外界将屏幕当前的状态传进来
func rateLaspace(isLaspace : Bool) {
//取出按钮总数
let count = subviews.count
//设置自身的宽度
self.frame.size.width = (superview?.frame.width)!
//根据传入的屏幕方法设置高度
self.frame.size.height = isLaspace ? kDockLaspaceHeight : kDockLaspaceHeight * CGFloat(count)
self.frame.origin.y = (superview?.frame.height)! - frame.size.height
for var i = 0 ; i &i++ {
//根据角标取出按钮
let item = subviews[i]
//设置按钮的尺寸
item.frame.size.width = isLaspace ? frame.width/CGFloat(count) : frame.width
item.frame.size.height = kDockLaspaceHeight
item.frame.origin.x = isLaspace ? CGFloat(i) * item.frame.size.width : 0
item.frame.origin.y = isLaspace ? 0 : CGFloat(i) * item.frame.size.width
&-& 3.2 创建按钮(该部分的代码比较多,我们写在类扩展的函数中)
代码块一 : (该部分的两个函数是一起使用的)
override init(frame: CGRect) {
super.init(frame: frame)
//初始化子控件
setUpButton(&tabbar_blog&,type: .blog)
setUpButton(&tabbar_mood&,type: .mood)
setUpButton(&tabbar_photo&,type: .photo)
required init?(coder aDecoder: NSCoder) {
fatalError(&init(coder:) has not been implemented&)
代码块二 :
//给类扩充一个方法,用来创建子控件数
extension XFJBottom {
@objc private func setUpButton(imageName : String, type : ButtomMenuType ) {
//创建按钮
let iconButton = UIButton()
//绑定tag,方便点击按钮的时候可以传入对应的值
iconButton.tag = type.rawValue
//添加按钮
addSubview(iconButton)
//设置按钮图片(普通图片)
iconButton.setImage(UIImage(named: imageName), forState: .Normal)
//设置高亮图片
iconButton.setBackgroundImage(UIImage(named: &tabbar_separate_selected_bg&), forState: .Highlighted)
//监听按钮点击(这是oc的方法,一定要加上@objc)
iconButton.addTarget(self, action: &buttonClick:&, forControlEvents: .TouchUpInside)
八 中间模块
1 和底部模块基本一样,也是通过在XFJDock类中提供的roteLspaces (isLaspace : Bool)函数,用来最为将isLaspace的屏幕状态来计算该部分情况
2 注意 : 该部分横屏和竖屏不同的是,在横屏的时候能显示图片和文字,但是在屏幕竖屏的时候,只显示图片.所以这部分需要做判断.
3 在XFJDock类中懒加载中间部分,然后添加到dock中
//懒加载中间工具栏
private lazy var middleMenu : XFJTabBar = {
//创建中间工具栏
let middleMenu = XFJTabBar()
self.addSubview(middleMenu)
//设置中间工具栏底部不变,顶部随着父控件拉伸而拉伸
middleMenu.autoresizingMask = .FlexibleTopMargin
return middleMenu
4 根据传入的屏幕方向,计算中间模块的尺寸
//根据外界传入的屏幕方向,计算高度和宽度
func roteTabLaspace(isLaspace : Bool) {
//中间部分的子控件总数
let count = subviews.count
//宽度跟随父控件
frame.size.width = (superview?.frame.width)!
frame.size.height = kDockLaspaceHeight * CGFloat(count)
for var i = 0 ; i & i++ {
//取出item
let item = subviews[i]
//设置尺寸
item.frame.size.width = (superview?.frame.width)!
item.frame.size.height = kDockLaspaceHeight
item.frame.origin.x = 0
item.frame.origin.y = item.frame.size.height * CGFloat(i)
5 添加中间模块的按钮(由于该部分的代码比较多,那么我们写在类扩展的方法中)
代码块一 :
//重写initWithFrame
override init(frame: CGRect) {
super.init(frame: frame)
//添加标题
setUpTabBarItem(imageName: &tab_bar_feed_icon&, title: &全部动态&)
setUpTabBarItem(imageName: &tab_bar_passive_feed_icon&, title: &与我相关&)
setUpTabBarItem(imageName: &tab_bar_pic_wall_icon&, title: &照片墙&)
setUpTabBarItem(imageName: &tab_bar_e_album_icon&, title: &电子相框&)
setUpTabBarItem(imageName: &tab_bar_friend_icon&, title: &好友&)
setUpTabBarItem(imageName: &tab_bar_e_more_icon&, title: &其它&)
required init?(coder aDecoder: NSCoder) {
fatalError(&init(coder:) has not been implemented&)
代码块二 :
//MARK: - 添加中间的子标题
extension XFJTabBar {
private func setUpTabBarItem(imageName imageName : String, title : String) {
//创建按钮
let button = XFJItemBtn()
button.tag = subviews.count
//添加按钮
addSubview(button)
//设置普通按钮
button.setTitle(title, forState: .Normal)
//设置普通图片
button.setImage(UIImage(named: imageName), forState: .Normal)
//设置高亮图片
button.setBackgroundImage(UIImage(named: &tabbar_separate_selected_bg&), forState: .Selected)
//监听按钮
button.addTarget(self, action: &buttonClick:&, forControlEvents: .TouchDown)
6 处理中间部分按钮选中和反选中情况
&-& 6.1 创建一个属性来记录按钮的状态
//定义一个属性,用来记录按钮点击的状态
private var selectButton = UIButton?()
&-& 6.2 处理按钮
/MARK: - 实现事件监听的方法
extension XFJTabBar {
@objc private func buttonClick(button : UIButton) {
//如果selectButton?.ta有值就用它的值,否则就用0
let tag = selectButton?.tag ?? 0
//实现代理方法
tabBarItemDelegate?.XFJTabBarItem!(tag, to: button.tag)
selectButton?.selected = false
selectButton = button
selectButton?.selected = true
7 取消按钮的高亮状态
&-& 7.1 创建桥接文件(如果自己不想配置,就让系统体你配置)
&-& 7.2 创建OC文件
&-& 7.3 在OC文件中重写按钮的高亮方法
- (void)setHighlighted:(BOOL)highlighted{
8 自定义按钮
&-& 8.1 自定义原因 : 由于我们需要修改当屏幕是横屏和竖屏两种状态下,按钮的文字出现与隐藏的效果,需要用自定义来解决
&-& 8.2 创建继承XFJCustomBtn的自定义文件
&-& 8.3 重写系统的init(frame: CGRect)方法,并且做相关设置(代码里有说明)
class XFJItemBtn: XFJCustomBtn {
//定义一个属性用来计算图片占的比例
ratio : CGFloat = 0.4
override init(frame: CGRect) {
super.init(frame: frame)
//仅仅让图片高亮
adjustsImageWhenHighlighted = false
//设置图片居中
imageView?.contentMode = .Center
required init?(coder aDecoder: NSCoder) {
fatalError(&init(coder:) has not been implemented&)
&-& 8.4 由于是继承按钮,所以重写按钮中的两个方法 : 一个是对按钮中标题的处理和另一个是对按钮中图片的处理(函数内部代码比较易懂,我这里就不多加说明了)
代码块一 : 按钮标题
//MARK: - 按钮标题
extension XFJItemBtn {
override func titleRectForContentRect(contentRect: CGRect) -& CGRect {
if frame.height == frame.width { //竖屏
return CGRectZero
}else{//横屏
let width : CGFloat = frame.width * (1 - ratio)
let height : CGFloat = frame.height
let x : CGFloat = frame.width * ratio
let y : CGFloat = 0
return CGRectMake(x, y, width, height)
代码块二 : 按钮图片
//MARK: - 按钮图片
extension XFJItemBtn {
override func imageRectForContentRect(contentRect: CGRect) -& CGRect {
if frame.height == frame.width { //竖屏
return bounds
}else{//横屏
let width : CGFloat = frame.width * ratio
let height : CGFloat = frame.height
let x : CGFloat = 0.0
let y : CGFloat = 0.0
return CGRectMake(x, y, width, height)
九 头像模块
1 在XFJDock类中对头像模块的懒加载和添加到dock中
//懒加载头像
private lazy var iconButton : XFJIconButton = {
//创建头像
let iconButton = XFJIconButton()
//添加头像
self.addSubview(iconButton)
return iconButton
2 通过XFJDock类中的roteLspaces (isLaspace : Bool)函数,将屏幕的状态值传入XFJIconButton类中的roteToLapace(isLapace : Bool)函数,用来计算头像的尺寸.
func roteToLapace(isLapace : Bool) {
//icon的高度
frame.size.height = isLapace ? kIconButtonLaspaceHeight : kIconProtraitWH
frame.size.width = isLapace ? kIconButtonLaspaceWidth : kIconProtraitWH
frame.origin.y = kIconLpaceY
frame.origin.x = ((superview?.frame.width)! - frame.width) * 0.5
self.isLapace = isLapace
3 添加头像中的文字和图片设置
//重写init方法
init(frame: CGRect) {
super.init(frame: frame)
//设置头像图片
setImage(UIImage(named: &icon&), forState: .Normal)
//设置文字
setTitle(&不良少年J&, forState: .Normal)
//设置文字显示位置
titleLabel?.textAlignment = .Center
required init?(coder aDecoder: NSCoder) {
fatalError(&init(coder:) has not been implemented&)
4 由于头像的本质是一个按钮,那么我们可以通过重写按钮中对图片和对标题的方法来对图片进行设置
头部按钮的图片设置代码 : (易懂)
//MARK: - 头部按钮的图片
extension XFJIconButton {
override func imageRectForContentRect(contentRect: CGRect) -& CGRect {
if frame.width == frame.height { //竖屏
return bounds
}else{//横屏
let width : CGFloat = kIconButtonLaspaceWidth
let height : CGFloat = kIconButtonLaspaceHeight
let x : CGFloat = 0.0
let y : CGFloat = 0.0
return CGRectMake(x, y, width, height)
头部按钮的标题设置代码 : (易懂)
//MARK: - 按钮的标题
extension XFJIconButton {
override func titleRectForContentRect(contentRect: CGRect) -& CGRect {
if frame.width == frame.height {//竖屏
return CGRectZero
}else{//横屏
let width : CGFloat = kIconButtonLaspaceWidth
let height : CGFloat = kIconTextHeight
let x : CGFloat = 0.0
let y : CGFloat = kIconButtonLaspaceHeight
return CGRectMake(x, y, width, height)
十 底部模块业务逻辑
1 需求 : 当点击底部按钮的时候,弹出控制器,并且点击弹出的控制器中的按钮,控制器消失.
2 采用方法 : 代理;协议
3 谁可以成为代理? 主控制器(XFJHomeViewController).原因是因为当点击底部按钮时,是有主控制器弹出子控制器.
4 弹出方式 ? model
5 设置枚举(外面通过switch的判断方式来选中model出对应的控制器)
//MARK : - 定义枚举
@objc enum ButtomMenuType : Int {
case photo
6 定义协议方法
//MARK : - 定义协议
@objc protocol XFJBottomDelegate : NSObjectProtocol {
//可实现的
optional func XFJBottomMenuClickItem(menu : XFJBottom, type : ButtomMenuType)
7 定义代理
//设置代理属性
weak var BottomMenuDelegate :XFJBottomDelegate?
8 监听底部模块按钮的点击(这是oc的方法,一定要加上@objc)
//监听按钮点击(这是oc的方法,一定要加上@objc)
iconButton.addTarget(self, action: &buttonClick:&, forControlEvents: .TouchUpInside)
8 处理按钮点击事件
//MARK: - 点击底部按钮,将相应的值传入协议方法中
extension XFJBottom {
@objc private func buttonClick(button : UIButton) {
BottomMenuDelegate?.XFJBottomMenuClickItem!(self, type: ButtomMenuType(rawValue: button.tag)!)
9 设置代理(在XFJHomeViewController的类中)
//设置底部工具条的代理
dock.getBottomMenu.BottomMenuDelegate = self
10 实现协议方法
//MARK : - 实现底部协议的方法
extension XFJHomeViewController {
func XFJBottomMenuClickItem(menu: XFJBottom, type: ButtomMenuType) {
switch type {
case .blog :
print(&点击了blog&)
case .mood :
//创建控制器
let moodVC = XFJMoodViewController()
//将该控制器作为导航控制器的根控制器
let nav = UINavigationController(rootViewController: moodVC)
//设置控制器样式
nav.modalPresentationStyle = .FormSheet
presentViewController(nav, animated: true, completion: nil)
print(&点击了mood&)
case .photo :
print(&点击了photo&)
十一 中间模块的业务逻辑
1 由于用户点击中间模块的按钮的时候,是对子控制器的切换,那么我们需要创建所有的子控制器(在XFJHomeViewController类中书写;考虑代码比较多,写在类扩展中)
//MARK : - 添加子控制器
extension XFJHomeViewController {
private func setUpAllChildController() {
//全部动态
let allDynamicStateController = XFJAllSegViewController()
allDynamicStateController.view.backgroundColor = UIColor.blueColor()
setUpNavController(allDynamicStateController)
//与我相关
let andMeCorrelationController = UIViewController()
andMeCorrelationController.view.backgroundColor = UIColor.redColor()
andMeCorrelationController.title = &与我相关&
setUpNavController(andMeCorrelationController)
let photoWallController = UIViewController()
photoWallController.view.backgroundColor = UIColor.yellowColor()
photoWallController.title = &照片墙&
setUpNavController(photoWallController)
//电子相框
let electronRahmenController = UIViewController()
electronRahmenController.view.backgroundColor = UIColor.purpleColor()
electronRahmenController.title = &电子相框&
setUpNavController(electronRahmenController)
let friendsController = UIViewController()
friendsController.view.backgroundColor = UIColor.orangeColor()
friendsController.title = &好友&
setUpNavController(friendsController)
let otherController = UIViewController()
otherController.view.backgroundColor = UIColor.whiteColor()
otherController.title = &其它&
setUpNavController(otherController)
//添加一个头像子控制器
let iconController = UIViewController()
iconController.view.backgroundColor = UIColor.brownColor()
iconController.title = &个人中心&
setUpNavController(iconController)
2 由于所有的子控制器都是作为导航控制器的根控制器,所以定义一个方法来设置导航控制器
//MARK : - 定义一个方法用来设置导航控制器
extension XFJHomeViewController {
private func setUpNavController(root : UIViewController){
let nav1 = UINavigationController(rootViewController: root)
addChildViewController(nav1)
3 设置中间子控制器的view
//MARK : - 设置内容的view
extension XFJHomeViewController {
private func setUpContentView() {
//判断是否子控制器存在,如果存在就直接返回
guard childViewControllers != [] else{
//创建一个属性
let contentive = UIView()
//添加contentView
view.addSubview(contentive)
//设置子控制器的view尺寸
contentive.frame.origin.x = dock.frame.width
contentive.frame.origin.y = 20.0
contentive.frame.size.height = view.frame.height - 20.0
//高度跟随父控件拉伸而拉伸
contentive.autoresizingMask = .FlexibleHeight
//用宽度和高度取出里面最小的
let ProtraitWidth = min(view.frame.height, view.frame.width)
//计算子控制器的宽度
contentive.frame.size.width = ProtraitWidth - kDockProtraitWidth
//赋值(用于屏幕旋转的时候更新x值)
self.contentive = contentive
4 定义协议
//MARK: - 协议方法
protocol XFJTabBarDelegate : NSObjectProtocol {
//这里用两个参数的原因是由于选中状态和没有选中状态需要切换,那么需要将不同的tag传入其中,才能令对应的控制器切换
optional func XFJTabBarItem(from : Int, to : Int)
5 设置代理
//定义代理
weak var tabBarItemDelegate : XFJTabBarDelegate?
6 实现代理方法(该部分代码是在监听按钮点击事件中个书写的)
//实现代理方法
tabBarItemDelegate?.XFJTabBarItem!(tag, to: button.tag)
7 设置代理
//设置中间部分工具条的代理
dock.getTabBarItem.tabBarItemDelegate = self
8 实现协议方法
//MARK: - 实现中间部分协议方法
extension XFJHomeViewController : XFJTabBarDelegate{
func XFJTabBarItem(from: Int, to: Int) {
//根据传入的参数,取出上移个view
let previousController = childViewControllers[from]
//移除上一个控制器的view
previousController.view.removeFromSuperview()
//取出下一个控制器的view
let nextVC = childViewControllers[to]
//将切换的子控制器的view添加到contentView中
contentive?.addSubview(nextVC.view)
//计算nextVC的尺寸
nextVC.view.frame = (contentive?.bounds)!
//下一个按钮的角标
selectButtonIndex = to
十二 头像模块业务逻辑处理
1 在XFJHomeViewController类中实现对头像按钮的监听
2 监听方法(需要加上@objc)
//监听头像点击
dock.getIcon.addTarget(self, action: &iconButtonClick&, forControlEvents: .TouchUpInside)
3 实现头像监听方法
//MARK : - 实现头像监听方法
extension XFJHomeViewController {
@objc private func iconButtonClick() {
//调用点击中间部分的内容
XFJTabBarItem(selectButtonIndex, to: childViewControllers.count - 1)
//调用取消选中状态
dock.getTabBarItem.unSelecButton()
十三 各个模块中的get方法
1 我们是在XFJHomeViewController类中设置其为各个模块的代理,但是我们在该类中是无法直接拿到对应的模块的代理,那么我们是通过什么办法的呢?&&& get方法
2 在各个模块创建的时候,我们直接提供一个get方法,这样很大的方便了外界可以间接的拿到模块对象
//对底部工具栏提供只读方法
var getBottomMenu : XFJBottom {
return bottomMenu
//对中间工具条提供只读的方法
var getTabBarItem : XFJTabBar {
return middleMenu
//给头像按钮提供一个只读的属性,让外界可以拿到iconButton按钮
var getIcon : XFJIconButton {
return iconButton
3 通过get方式拿到模块设置代理和对头像的监听
//设置底部工具条的代理
dock.getBottomMenu.BottomMenuDelegate = self
//设置中间部分工具条的代理
dock.getTabBarItem.tabBarItemDelegate = self
//监听头像点击
dock.getIcon.addTarget(self, action: &iconButtonClick&, forControlEvents: .TouchUpInside)
1 默认程序启动进入主界面,显示的是头像模块
2 在XFJTabBar提供一个方法取消选中状态
//提供一个方法取消选中状态(由外界调用)
func unSelecButton() {
selectButton?.selected = false
3 设置程序已启动进入主界面当前的角标为0
//设置一个属性当前按钮角标
private var selectButtonIndex : Int = 0
4 将该属性传入对头像按钮监听的方法中,就能实现默认选中头像模块了
//MARK : - 实现头像监听方法
extension XFJHomeViewController {
@objc private func iconButtonClick() {
//调用点击中间部分的内容
XFJTabBarItem(selectButtonIndex, to: childViewControllers.count - 1)
//调用取消选中状态
dock.getTabBarItem.unSelecButton()
1 中间模块中的导航条的标题进行处理UISegmentedControl
2 该部分没什么可以说的,比较简单,下面是代码
class XFJAllSegViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//设置背景颜色
view.backgroundColor = UIColor.whiteColor()
let seg = UISegmentedControl(items: [&全部&,&特别关心&,&好友动态&,&认证空间&])
navigationItem.titleView = seg
//设置颜色
seg.tintColor = UIColor.grayColor()
//设置默认选中第0个
seg.selectedSegmentIndex = 0
//设置选中文字
seg.setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.blackColor()], forState: .Normal)
//监听点击事件
seg.addTarget(self, action: &segClick&, forControlEvents: .TouchUpInside)
3 点击底部模块,model出控制器,对model出来的控制器相关设置
class XFJMoodViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//设置标题
self.title = &发表说说&
//设置颜色
view.backgroundColor = UIColor.redColor()
//设置导航条左边的内容
navigationItem.leftBarButtonItem = UIBarButtonItem(title: &关闭&, style: .Plain, target: self, action: &exit&)
//设置导航条右边的内容
navigationItem.rightBarButtonItem = UIBarButtonItem(title: &发表&, style: .Plain, target: self, action: &deliver&)
//Mark : - dismiss控制器
extension XFJMoodViewController {
@objc private func exit() {
dismissViewControllerAnimated(true, completion: nil)
1 总结的差不多了,只要我考虑到的情况,我都写在了里面,希望对个位能有所帮助吧.里面依旧有不完善的地方.后续想到了会完善.
2 逻辑适中,要求能理解协议的用法.明白怎么对屏幕横屏和竖屏的判断,通过横屏和竖屏对每个模块尺寸的设置.
3 最后大家如果觉得我写得还行,麻烦大家关注我的官方博客,有什么意见大家给我留言即可,谢谢!!!!}

我要回帖

更多关于 点击链接跳转到公众号 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信