标签 ios控件 下的文章

UIApplication常用设置

//
//  ViewController.swift
//  ios程序启动
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    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.
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesBegan(touches, withEvent: event)
        let app = UIApplication.sharedApplication()
        //设置联网状态
        app.networkActivityIndicatorVisible = app.networkActivityIndicatorVisible ? false : true
        //设置图标消息数字,需要先获得权限
        let userSeting = UIUserNotificationSettings(forTypes: UIUserNotificationType.Badge, categories: nil)
        app.registerUserNotificationSettings(userSeting)
        //再设置数字
        app.applicationIconBadgeNumber = 10
        //打开网址
        app.openURL(NSURL(string: "http://baidu.com")!)
    }

}

UIDatePickerView和UIToolbar的使用

自定义的xib类
//
//  KeyboardToolBar.swift
//  datepicker
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
//自定义协议,响应当前工具条的按钮点击事件
@objc protocol KeyboardToolBarDelagate
{
    optional func keyboardToolBarDownButtonClicked()
}
class KeyboardToolBar: UIToolbar {
    @IBOutlet weak var preButton: UIBarButtonItem!

    @IBOutlet weak var downButton: UIBarButtonItem!

    @IBAction func downClick(sender: UIBarButtonItem) {
        self.keyboardDelagate?.keyboardToolBarDownButtonClicked?()
    }
    weak var keyboardDelagate:KeyboardToolBarDelagate!
    //快速初始化
    class func instance()->KeyboardToolBar
    {
        //记载xib
        let toolBar = NSBundle.mainBundle().loadNibNamed("KeyboardToolBar", owner: nil, options: nil).last as! KeyboardToolBar
        return toolBar
    }

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
}
在控制器中的调用
//
//  ViewController.swift
//  datepicker
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController,KeyboardToolBarDelagate {
    var datePicker:UIDatePicker!

    @IBOutlet weak var textField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()
        //创建UIDatePickerView
        self.datePicker = UIDatePicker()
        //设置时间地区
        self.datePicker.locale = NSLocale(localeIdentifier: "zh")
        //设置时间显示模式
        self.datePicker.datePickerMode = UIDatePickerMode.Date
        //设置UITexField的键盘
        self.textField.inputView = self.datePicker
        //返回自定义的xib对象
        let keyBoardToolBar = KeyboardToolBar.instance()
        //设置自定义xib对象的代理
        keyBoardToolBar.keyboardDelagate = self
        //设置键盘附件
        self.textField.inputAccessoryView = keyBoardToolBar
//        self.codeKeyboard()

//        self.view.addSubview(toolBar)
        // Do any additional setup after loading the view, typically from a nib.
    }
    //代理方法,把在键盘区的日期放到UITextField中
    func keyboardToolBarDownButtonClicked() {
        //获得Date对象
        let date = self.datePicker.date
        //初始化 NSDateFormate 对象
        let dateFormat = NSDateFormatter()
        //设置 NSDateFormate 对象的格式
        dateFormat.dateFormat = "yyyy-MM-dd"
        //会的日期对象格式化成字符串的值
        self.textField.text = dateFormat.stringFromDate(date)
        //收回键盘
        self.view.endEditing(true)
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    //代码创建键盘 barTool
    func codeKeyboard()
    {
        //创建 对象
        let toolBar = UIToolbar()
        //获得宽度
        let toolBarW = UIScreen.mainScreen().bounds.size.width
        //设置 toolBar的宽高,不设置不能显示
        toolBar.bounds = CGRectMake(0, 0, toolBarW, 50)
        //添加工具栏按钮
        let preButtonItem = UIBarButtonItem(title: "上一页", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
        //添加间隔
        let fixButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
        fixButtonItem.width = 20
        //按纽
        let nextButtonItem = UIBarButtonItem(title: "下一页", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
        //添加间隔,注意这个和 fixButtonItem 的不同
        let flexiButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
        let downtButtonItem = UIBarButtonItem(title: "down", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
        //把控件放到工具条中
        toolBar.items = [preButtonItem,fixButtonItem,nextButtonItem,flexiButtonItem,downtButtonItem]
        // 把工具条设置成当前键盘 
        self.textField.inputAccessoryView = toolBar
    }

}

模仿qq好友列表

注意点:UIButton图片的几个不常用的属性

模型类
import UIKit
//好友模型类
class QQFriend: NSObject {
    var icon:NSString!//用户头像
    var intro:NSString!//签名
    var name:NSString!//名字
    var vip:NSNumber!//是否是vip
    //便捷构造器
    convenience init(dic:[String : AnyObject]) {
        self.init()
        //kvc用法
        self.setValuesForKeysWithDictionary(dic)
    }
}
import UIKit
//好友分组类
class QQFriendGroup: NSObject {
    var friends:[QQFriend] = []//存放qq好友对象数组
    var name:NSString!//分组名称
    var online:NSNumber!//分组在线人数
    var hideGroup:Bool = true//是否隐藏,默认是隐藏的
    //快速plist文件中初始化对象数组
    class func instanceWithFile()->[QQFriendGroup]
    {
        let path = NSBundle.mainBundle().pathForResource("friends", ofType: "plist")
        let data = NSArray(contentsOfFile: path!)
        var qqFriendGroups:[QQFriendGroup] = []
        for var i = 0;i < data!.count;i++
        {
            let qqFriendGroupTemp = QQFriendGroup(dic: data![i] as! NSDictionary)
            qqFriendGroups.append(qqFriendGroupTemp)
        }
        return qqFriendGroups
    }
    //快速实例化方法
    convenience init(dic:NSDictionary) {
        self.init()
        self.name = dic["name"] as! NSString
        self.online = dic["online"] as! NSNumber
        let friendsData = dic["friends"] as! NSArray
        for var i = 0;i < friendsData.count;i++
        {
            let qqFriend:QQFriend! = QQFriend(dic: friendsData[i] as! [String : AnyObject])
            self.friends.append(qqFriend)
        }
    }
}
自定义UITableView的Header类
//
//  QQFriendHeader.swift
//  QQFriend
//
//  Created by zhang on 16/1/10.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
//自定义协议
@objc protocol QQFriendHeaderShowFriendButtonClick
{
    optional func QQFriendHeaderShowFriendButtonClicked(tag:Int)
}
//自定义header类,注意继承自 UITableViewHeaderFooterView
class QQFriendHeader: UITableViewHeaderFooterView {

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    weak var buttonView:UIButton!
    weak var lableView:UILabel!
    weak var qqFriendGroup:QQFriendGroup!
        {
        didSet
        {
            self.assignSubViewContent()
        }
    }
    weak var delegate:QQFriendHeaderShowFriendButtonClick!//代理参数
    //可重用Header
    class func instance(tableView:UITableView)->QQFriendHeader
    {
        let identifier = "QQFriendSectionHeader"
        var header:UITableViewHeaderFooterView! = tableView.dequeueReusableHeaderFooterViewWithIdentifier(identifier)
        if header == nil
        {
            header = QQFriendHeader(reuseIdentifier: identifier)
        }
        let temp = header as! QQFriendHeader
        return temp
    }
    //重写父类的构造方法,添加需要的子控件
    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        //自定义button,用于覆盖于view表层,响应点击时间
        let buttonView = UIButton(type: UIButtonType.Custom)
        buttonView.setImage(UIImage(imageLiteral: "buddy_header_arrow"), forState: UIControlState.Normal)
        buttonView.imageView?.contentMode = UIViewContentMode.Center//图片不压缩
        buttonView.imageView?.clipsToBounds = false//图片不裁剪
        buttonView.setBackgroundImage(UIImage(imageLiteral: "buddy_header_bg"), forState: UIControlState.Normal)//设置背景
        buttonView.setBackgroundImage(UIImage(imageLiteral: "buddy_header_bg_highlighted"), forState: UIControlState.Highlighted)
        buttonView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left//设置内容堆对齐方式
        buttonView.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)//设置内容边距
        buttonView.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)//设置标题颜色
        buttonView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0)//设置标题边距
        buttonView.addTarget(self, action: "buttonClick:", forControlEvents: UIControlEvents.TouchDown)//绑定点击事件
        self.buttonView = buttonView
        let lableView = UILabel()
        self.lableView = lableView
        //加入父控件
        self.contentView.addSubview(self.buttonView)
        self.contentView.addSubview(self.lableView)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //给子控件赋值
    func assignSubViewContent()
    {
        let rotation = CGFloat(self.qqFriendGroup.hideGroup ? 0 : M_PI_2)//设置图片旋转,不设置的话,会出现因为重用而产生的bug
        self.buttonView.imageView?.transform = CGAffineTransformMakeRotation(rotation)
        self.buttonView.setTitle(self.qqFriendGroup.name as String, forState: UIControlState.Normal)
        self.lableView.text = "\(self.qqFriendGroup.online)/\(self.qqFriendGroup.friends.count)"
    }
    //往headerView中添加子控件的时候会调用
    //当改变了headerView的frame会调用
    override func layoutSubviews() {
        super.layoutSubviews()
        self.buttonView.setTitle(self.qqFriendGroup.name as String, forState: UIControlState.Normal)
        buttonView.frame = self.bounds

        //根据文字来设置labl的rect,用boundingRectWithSize的话需要字串是 NSString 格式,而且需要填一些参数,第二种简便些
        //lableText.boundingRectWithSize(CGSize.init(width: CGFloat.max, height: CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize()], context: nil)
        let lableSize = CGSizeMake((self.lableView?.textRectForBounds(CGRectMake(0, 0, CGFloat.max, CGFloat.max), limitedToNumberOfLines: 1).size.width)!, self.frame.size.height)

        lableView.frame = CGRectMake(self.frame.size.width - (lableSize.width + 10), 0, lableSize.width,lableSize.height)
    }
    //响应点击
    func buttonClick(sender:UIButton)
    {

        //缩放图片
        let rotation = CGFloat(self.qqFriendGroup.hideGroup ? M_PI_2 : 0)
        self.qqFriendGroup.hideGroup = self.qqFriendGroup.hideGroup ? false : true//修改显示状态
        UIView.animateWithDuration(0.5, animations: {
            sender.imageView?.transform = CGAffineTransformMakeRotation(rotation)
        })
        //注意这里调用的方式
        self.delegate?.QQFriendHeaderShowFriendButtonClicked?(self.tag)
    }
}
在controller中的调用

import UIKit //遵守了几个协议 class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,QQFriendHeaderShowFriendButtonClick { //懒加载好有分组 lazy var qqFriendGroups:[QQFriendGroup] = QQFriendGroup.instanceWithFile() @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() self.tableView.dataSource = self//指定数据源 self.tableView.delegate = self//指定代理 self.tableView.sectionHeaderHeight = 44//设置行高 // self.tableView.sectionFooterHeight = 0 // print(self.qqFriendGroups) // 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. } //返回分组数量 func numberOfSectionsInTableView(tableView: UITableView) -> Int { return self.qqFriendGroups.count } //返回对应cell func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let identifier = "QQFriendCell" var cell:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(identifier) if cell == nil { cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: identifier) } cell.textLabel?.text = self.qqFriendGroups[indexPath.section].friends[indexPath.row].name as String cell.detailTextLabel?.text = self.qqFriendGroups[indexPath.section].friends[indexPath.row].intro as String cell.imageView?.image = UIImage(imageLiteral: (self.qqFriendGroups[indexPath.section].friends[indexPath.row].icon as String)) return cell } //返回分组纪录条数 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //因为默认是要不显示cell的,所以这里根据,分组对象的属性做了下判断, if self.qqFriendGroups[section].hideGroup { return 0 } else { return self.qqFriendGroups[section].friends.count } } //返回分组头的标题 // func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { // return self.qqFriendGroups[section].name as? String // } //返回自定义的头 func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let header = QQFriendHeader.instance(tableView) header.qqFriendGroup = self.qqFriendGroups[section] header.delegate = self//设置代理 header.tag = section//用于之后点击cell传递值来锁定分组 return header } // func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { // return nil // } override func prefersStatusBarHidden() -> Bool { return true } //代理cell点击的方法 func QQFriendHeaderShowFriendButtonClicked(tag:Int) { let indexSet = NSIndexSet(index: tag) self.tableView.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Fade)//重新加载所点击的分组 } }

qq聊天界面模拟

模拟简化的qq聊天的界面
需要注意的有:计算字符串所占的大小,扩展的使用,图片的 stretchableImageWithLeftCapWidth方法的使用,通知的使用,键盘的通知事件的使用, TableView的一些方法和属性
代码

数据模型类
//
//  Message.swift
//  QQ
//
//  Created by zhang on 16/1/7.
//  Copyright © 2016年 jin. All rights reserved.
//
//时间lable字体大小
let timeFontSize:CGFloat = 15
//文本lable字体大小
let textFontSize:CGFloat = 16
//按钮内边距
let buttonEdgeInsets:CGFloat = 20
import UIKit
class Message: NSObject {
    var text:NSString!
    var time:NSString!
    var type:NSNumber!
        {
        //变量发生改变之后执行这个方法
        didSet
        {
            if self.type == 0
            {
                self.icon = "me"
            }
            else
            {
                self.icon = "other"
            }
        }
    }
    var hiddenTime:Bool = true
    var icon:String!
    convenience init(dic:[String : AnyObject]) {
        self.init()
        self.setValuesForKeysWithDictionary(dic)
    }
}
cell位置信息类
//
//  MessageFrame.swift
//  QQ
//
//  Created by zhang on 16/1/7.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class MessageFrame: NSObject {
    let iconFrame:CGRect
    let timeFrame:CGRect
    let textFrame:CGRect
    let cellHeight:CGFloat
    let message:Message
    //快速实例话的方法
    class func instanceWithFile()->[MessageFrame]
    {
        let path = NSBundle.mainBundle().pathForResource("messages", ofType: "plist")
        let data = NSArray(contentsOfFile: path!)
        var messageFrames:[MessageFrame] = []
        //这个变量用于记录上一个消息时间,用这个判断当前messageCell是否显示时间lable
        var flag:NSString = ""
        for var i = 0;i < data?.count;i++
        {
            let message = Message(dic: data![i] as! [String : AnyObject])
            //判断是否显示时间
            if flag.isEqualToString(message.time as String)
            {
                message.hiddenTime = false
            }
            flag = message.time
            messageFrames.append(MessageFrame.init(message: message))
        }
        return messageFrames
    }
    convenience init(message:Message) {
        let margin:CGFloat = 10
        //计算头像frame
        var iconFrame:CGRect = CGRect.zero
        let iconW:CGFloat = 50
        let iconH:CGFloat = 50
        var iconX:CGFloat = margin
        let iconY:CGFloat = margin
        //当是自己的消息的时候,更改坐标位置
        if message.type == 0
        {
            iconX = UIScreen.mainScreen().bounds.size.width - margin - iconW
        }
        iconFrame = CGRectMake(iconX, iconY, iconW, iconH)
        //时间lable
        var timeFrame:CGRect = CGRect.zero
        if message.hiddenTime
        {
            let timeW = UIScreen.mainScreen().bounds.size.width
            //计算文字所需要的大小
            let timeH = message.time.boundingRectWithSize(CGSizeMake(CGFloat.max, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(timeFontSize)], context: nil).size.height
            timeFrame = CGRectMake(0, 0, timeW, timeH)
        }
        //消息Button
        //计算消息文本需要的大小
        let textSize = message.text.boundingRectWithSize(CGSize(width: UIScreen.mainScreen().bounds.size.width - (iconFrame.size.width * 2) - (margin * 4),height: CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(textFontSize)], context: nil).size
        var textX = CGRectGetMaxX(iconFrame) + margin
        let textY = CGRectGetMaxY(timeFrame) + margin
        //当是自己的消息的时候,更改横坐标
        if message.type == 0
        {
            textX = iconFrame.origin.x - textSize.width - margin - (buttonEdgeInsets * 2)
        }
        //因为设置了Button内边距,所以需要加上内边距
        let textFrame = CGRectMake(textX, textY, textSize.width + (buttonEdgeInsets * 2), textSize.height + 40)
        //cell高度
        let cellHeight = (CGRectGetMaxY(textFrame) > CGRectGetMaxY(iconFrame) ? CGRectGetMaxY(textFrame) : CGRectGetMaxY(iconFrame)) + margin
        //执行构造方法
        self.init(iconFrame:iconFrame,timeFrame:timeFrame,textFrame:textFrame,cellHeight:cellHeight,message:message)
    }
    init(iconFrame:CGRect,timeFrame:CGRect,textFrame:CGRect,cellHeight:CGFloat,message:Message) {
        self.iconFrame = iconFrame
        self.timeFrame = timeFrame
        self.textFrame = textFrame
        self.cellHeight = cellHeight
        self.message = message
    }
}
自定义的cell模型类
//
//  MessageCell.swift
//  QQ
//
//  Created by zhang on 16/1/7.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class MessageCell: UITableViewCell {

    var messageFrame:MessageFrame!
        {
        didSet
        {
            self.assignSubViewsContent()
            self.assignSubViewsFrame()
        }
    }
    var iconView:UIImageView!
    var timeView:UILabel!
    var textView:UIButton!
    //便捷构造器
    class func instanceWithTableView(tableView:UITableView)->MessageCell
    {
        let identifier = "qqcell"
        var cell = tableView.dequeueReusableCellWithIdentifier(identifier)
        if cell == nil
        {
            cell = MessageCell(style: UITableViewCellStyle.Default, reuseIdentifier: identifier)
        }
        let temp = cell as! MessageCell
        return temp
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        //设置头像
        self.iconView = UIImageView()
        self.iconView.layer.cornerRadius = 25
        self.iconView.layer.masksToBounds = true
        //设置时间
        self.timeView = UILabel()
        self.timeView.font = UIFont.systemFontOfSize(timeFontSize)
        self.timeView.textAlignment = NSTextAlignment.Center
        //设置内容
        self.textView = UIButton()
        self.textView.titleLabel?.numberOfLines = 0
        self.textView.titleLabel?.font = UIFont.systemFontOfSize(textFontSize)
        self.textView.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
        self.textView.titleEdgeInsets = UIEdgeInsets(top: buttonEdgeInsets, left: buttonEdgeInsets, bottom: buttonEdgeInsets, right: buttonEdgeInsets)
        //添加进父控件
        self.addSubview(self.iconView)
        self.addSubview(self.timeView)
        self.addSubview(self.textView)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //给子控件赋值
    func assignSubViewsContent()
    {
        self.iconView.image = UIImage(imageLiteral: self.messageFrame.message.icon)
        self.timeView.text = self.messageFrame.message.time as String
        self.textView.setTitle(self.messageFrame.message.text as String, forState: UIControlState.Normal)
        //好友和自己发送的图片是不一样的,这例做下处理
        var normalImageName = ""
        var higlightedImageName = ""
        if self.messageFrame.message.type == 0
        {
            normalImageName = "chat_send_nor"
            higlightedImageName = "chat_send_press_pic"
        }
        else
        {
            normalImageName = "chat_recive_nor"
            higlightedImageName = "chat_recive_press_pic"
        }
        //实例化图片对象并调用扩展的方法的到需要的图片
        let normalImage = UIImage(imageLiteral: normalImageName).changeImage()
        let highlightedImage = UIImage(imageLiteral: higlightedImageName).changeImage()
        //设置不同状态的背景图片
        self.textView.setBackgroundImage(normalImage, forState: UIControlState.Normal)
        self.textView.setBackgroundImage(highlightedImage, forState: UIControlState.Highlighted)
        //清除当前cell背景颜色
        self.backgroundColor = UIColor.clearColor()
        //设置消息主题内容
        self.textView.setTitle(self.messageFrame.message.text as String, forState: UIControlState.Highlighted)

    }
    //设置位置
    func assignSubViewsFrame()
    {
        self.iconView.frame = self.messageFrame.iconFrame
        self.timeView.frame = self.messageFrame.timeFrame
        self.textView.frame = self.messageFrame.textFrame
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}
扩展image
//
//  ImageExtension.swift
//  QQ
//
//  Created by admin on 16/1/8.
//  Copyright © 2016年 jin. All rights reserved.
//

import Foundation
import UIKit
//扩展 UIImage
extension UIImage
{
    func changeImage()->UIImage
    {
        //这个方法处理之后的图片在改变大小的时候边缘不会变化
        return self.stretchableImageWithLeftCapWidth(Int(self.size.width / 2), topCapHeight: Int(self.size.height / 2))
    }
}
最后就是在控制器中的调用了
//
//  ViewController.swift
//  QQ
//
//  Created by zhang on 16/1/7.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate {
    lazy var messageFrames:[MessageFrame] = MessageFrame.instanceWithFile()
    @IBOutlet var sendMessageView: UIView!
    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        //去掉cell的分割线
        self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        self.tableView.allowsSelection = false
        //设置背景色
        self.tableView.backgroundColor = UIColor(red: 125/255, green: 125/255, blue: 125/255, alpha: 1)
        // Do any additional setup after loading the view, typically from a nib.
        //订阅键盘位置改变的通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardChange:", name: UIKeyboardWillChangeFrameNotification, object: nil)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        //
    }
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.messageFrames.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = MessageCell.instanceWithTableView(self.tableView)
        cell.messageFrame = self.messageFrames[indexPath.row]
        return cell
    }
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return self.messageFrames[indexPath.row].cellHeight
    }
    func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
        return nil
    }
    // table代理方法
    func scrollViewDidScroll(scrollView: UIScrollView) {
        self.view.endEditing(true)
    }
    func keyboardChange(not:NSNotification)
    {
        //键盘位置没有发生变化的时候的位置信息,注意这里的转换
//        let beginRect = not.userInfo!["UIKeyboardFrameEndUserInfoKey"]!.CGRectValue
        //也可以直接取得,不过是一个可选类型
        let beginRect = not.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue
        //键盘位置没有发生变化后的位置信息
        let endRect = not.userInfo!["UIKeyboardFrameBeginUserInfoKey"]!.CGRectValue
        let y = beginRect.origin.y - endRect.origin.y
        //动画效果,注意这里的类型转换
        UIView.animateWithDuration(NSTimeInterval(not.userInfo![UIKeyboardAnimationDurationUserInfoKey]!.floatValue), animations: {
            self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, y)
        })
    }
    //文章本框键盘发送方法
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        self.sendMessage(textField.text!, type: 0)
        //使用dispatch延时发送恢复消息
        let minseconds = 2 * Double(NSEC_PER_SEC)
        let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
        dispatch_after(dtime, dispatch_get_main_queue(), {
            self.sendMessage("哈哈哈",type: 1)
        })
        return true
    }
    //发送消息
    func sendMessage(text:NSString,type:NSNumber)
    {
        //初始化信息数据
        let message = Message()
        message.text = text
        message.type = type
        //获取时间
        let data = NSDate()
        let dataFormat = NSDateFormatter()
        dataFormat.dateFormat = "HH:mm"
        message.time = dataFormat.stringFromDate(data)
        //判断是否显示时间 lable
        if message.time.isEqualToString((self.messageFrames.last?.message.time)! as String)
        {
            message.hiddenTime = false
        }
        //添加进数据来源数组
        self.messageFrames.append(MessageFrame.init(message: message))
        //获得消息的 indexPath
        let indexPath = NSIndexPath(forRow: self.messageFrames.count - 1, inSection: 0)
        //插入cell
        self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
        //动画效果
        UIView.animateWithDuration(2, animations: {
            //滚动到当前发送的信息位置
            self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)
        })

    }
}

模仿微博页面,swift版本

如题,对文博页面的简单的模仿,和之前团购那个不一样的是,这个是用代码去添加cell的子控件,还需要计算文本内容所占的大小,还有就是注意到了代理方法的执行是有一定顺序的,以后需要注意
代码部分:

首先是数据的加载,这次的数据的加载和之前的有点不同,除了加载数据之外,还需要计算出控件需要的大小,分成了两个类
//
//  Microblog.swift
//  微博
//
//  Created by admin on 16/1/6.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
//记录下两个lable的字体的大小,方便之后计算
let nameFontSize:CGFloat = 15
let textFontSize:CGFloat = 17
//模型类
class Microblog: NSObject {
    var name:NSString!
    var icon:NSString!
    var text:NSString!
    var picture:NSString!
    var vip:NSNumber!
    //便捷构造器
    convenience init(dic:[String : AnyObject]) {
        self.init()
        self.setValuesForKeysWithDictionary(dic)
    }
}
//
//  MicroblogFram.swift
//  微博
//
//  Created by admin on 16/1/7.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
//控件位置信息类
class MicroblogFram: NSObject {
    let iconFram:CGRect
    let nameFram:CGRect
    let vipFram:CGRect
    let textFram:CGRect
    let pictureFram:CGRect
    let cellHeight:CGFloat
    let microblog:Microblog
    //构造方法
    init(iconFram:CGRect,nameFram:CGRect,vipFram:CGRect,textFram:CGRect,pictureFram:CGRect,cellHeight:CGFloat,microblog:Microblog) {
        self.iconFram = iconFram
        self.nameFram = nameFram
        self.vipFram = vipFram
        self.textFram = textFram
        self.pictureFram = pictureFram
        self.cellHeight = cellHeight
        self.microblog = microblog
    }
    //便捷构造器,使用microblog对象来初始化microblogfram
    convenience init(microblog:Microblog) {
        //间距
        let margin:CGFloat = 10
        //图标fram计算
        let iconFram:CGRect = CGRectMake(10, 10, 50, 50)
        //通过字符串计算字符所需的大小
        let nameSize = microblog.name.boundingRectWithSize(CGSizeMake(CGFloat.max, CGFloat.max), options: NSStringDrawingOptions.UsesFontLeading, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(nameFontSize)], context: nil).size
        let nameX = CGRectGetMaxX(iconFram) + margin
        let nameY = ((iconFram.size.height - nameSize.height) / 2) + margin
        let nameFram = CGRectMake(nameX, nameY, nameSize.width, nameSize.height)
        //vip
        var vipFram = CGRectMake(0, 0, 0, 0)
        if microblog.vip == 1
        {
            let vipSize = CGSizeMake(14, 14)
            let vipX = CGRectGetMaxX(nameFram) + margin
            let vipY = (nameFram.size.height - vipSize.height) / 2 + nameFram.origin.y
            vipFram = CGRectMake(vipX, vipY, vipSize.width, vipSize.height)
        }
        //text
        //通过字符串计算字符所需要占用的大小,注意 NSStringDrawingOptions.UsesLineFragmentOrigin 这个选项会把文字换行的高度计算起来,UsesFontLeading只计算一行的高度
        let textSize = microblog.text.boundingRectWithSize(CGSizeMake(UIScreen.mainScreen().bounds.size.width - (margin * 2), CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(textFontSize)], context: nil).size
        let textX = margin
        let textY = CGRectGetMaxY(iconFram) + margin
        let textFram = CGRectMake(textX, textY, textSize.width, textSize.height)
        //整个cell的高度
        var cellHeight = CGRectGetMaxY(textFram) + margin
        //picture
        var pictureFram = CGRectMake(0, 0, 0, 0)
        if microblog.picture != nil
        {
            let pictureSize = CGSizeMake(100, 100)
            let pictureX = margin
            let pictureY = CGRectGetMaxY(textFram) + margin
            pictureFram = CGRectMake(pictureX, pictureY, pictureSize.width, pictureSize.height)
            //如果有图片,修改cell高度
            cellHeight = CGRectGetMaxY(pictureFram) + margin
        }
        //初始化类
        self.init(iconFram: iconFram,nameFram: nameFram,vipFram: vipFram,textFram: textFram,pictureFram: pictureFram,cellHeight: cellHeight,microblog:microblog)
    }
    //读取plist中的数据
    class func instanceWithFile()->[MicroblogFram]
    {
        let path:String! = NSBundle.mainBundle().pathForResource("microblog", ofType: "plist")
        let data = NSArray(contentsOfFile: path)
        var microblogs:[MicroblogFram] = []
        for var i = 0;i < data?.count;i++
        {
            microblogs.append(MicroblogFram.init(microblog: Microblog.init(dic: data![i] as! [String : AnyObject])))
        }
        return microblogs
    }
}
自定义cell类,没有用到xib,注意下变量的 didSet 方法
//
//  MicroblogCell.swift
//  微博
//
//  Created by admin on 16/1/6.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
//自定义cell
class MicroblogCell: UITableViewCell {
    var microblogFram:MicroblogFram?
    {
        //当变量发生改变时会触发这个方法
        didSet
        {
            //添加子控件
            self.assignSubviewContent()
            //调整子控件位置
            self.assignSubViewFram()
        }
    }
    //存储子控件的变量
    var nameView:UILabel!
    var iconView:UIImageView!
    var textView:UILabel!
    var pictureView:UIImageView!
    var vipView:UIImageView!
    //快速初始化
    class func instance(tableView:UITableView)->MicroblogCell
    {
        //尝试从缓冲池中读取内容
        var cell = tableView.dequeueReusableCellWithIdentifier("cell")
        if cell == nil
        {
            cell = MicroblogCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
        }
        let temp = cell as! MicroblogCell
        return temp
    }
    //重写父类的构造方法
    override init(style: UITableViewCellStyle, reuseIdentifier: String?)
    {
        //执行父类的构造器
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        //执行自己的方法,就是添加子控件
        self.nameView = UILabel()
        self.nameView.font = UIFont.systemFontOfSize(nameFontSize)
        self.iconView = UIImageView()
        self.textView = UILabel()
        self.textView.font = UIFont.systemFontOfSize(textFontSize)
        //文本内容可能需要换行,这里设置下行数
        self.textView.numberOfLines = 0
        self.pictureView = UIImageView()
        self.vipView = UIImageView()
        //添加进父控件
        self.addSubview(self.nameView)
        self.addSubview(self.iconView)
        self.addSubview(self.textView)
        self.addSubview(self.pictureView)
        self.addSubview(self.vipView)
    }
    //这个方法不知道什么用,重写上面构造方法的时候系统自动加上来的
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //给子控件赋值
    func assignSubviewContent()
    {
        self.nameView.text = self.microblogFram?.microblog.name as? String
        self.iconView.image = UIImage(imageLiteral: self.microblogFram?.microblog.icon as! String)
        self.textView.text = self.microblogFram?.microblog.text as? String
        if self.microblogFram?.microblog.picture != nil
        {
            self.pictureView.image = UIImage(imageLiteral: self.microblogFram?.microblog.picture as! String)
        }
        if self.microblogFram?.microblog.vip == 1
        {
            self.vipView.image = UIImage(imageLiteral:  "vip")
            self.vipView.hidden = false
            self.nameView.textColor = UIColor.redColor()
        }
        else
        {
            self.vipView.hidden = true
            self.nameView.textColor = UIColor.blackColor()
        }
    }
    //设置子控件位置大小
    func assignSubViewFram()
    {
        self.nameView.frame = (self.microblogFram?.nameFram)!
        self.iconView.frame = (self.microblogFram?.iconFram)!
        self.textView.frame = (self.microblogFram?.textFram)!
        self.pictureView.frame = (self.microblogFram?.pictureFram)!
        self.vipView.frame = (self.microblogFram?.vipFram)!
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}
然后就是在控制器中的调用了
//
//  TableViewController.swift
//  微博
//
//  Created by admin on 16/1/6.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class TableViewController: UITableViewController {

    lazy var microblogs:[MicroblogFram] = MicroblogFram.instanceWithFile()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return self.microblogs.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = MicroblogCell.instance(tableView)

        cell.microblogFram = self.microblogs[indexPath.row]
        // Configure the cell...

        return cell
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return self.microblogs[indexPath.row].cellHeight
    }
}