分类 iOS控件 下的文章

自定义UIWindow

//
//  AppDelegate.swift
//  UIWindow
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        //已经在项目去掉了默认启动的 storyboard
        //初始化 UIWindow
        let window = UIWindow()
        //设置大小颜色,方便看效果
        window.bounds = UIScreen.mainScreen().bounds
        window.backgroundColor = UIColor.grayColor()
        //初始化控制器
        let controller = TestViewController()
        //设置window对象的根控制器为当前创建的控制器,因为没有root控制器,所以会显示出window设置的背景色
        window.rootViewController = controller
        //这里的注释部分是设置根控制器的view,设置了之后就会显示这个view,白色的,这里是用代码创建的,当然也可以换成加载xib
//        let view = UIView()
//        view.frame = window.bounds
//        view.backgroundColor = UIColor.whiteColor()
//        
//        controller.view = view
        self.window = window
        //设置当前窗口位主窗口并可见
        self.window?.makeKeyAndVisible()
        // Override point for customization after application launch.
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

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)
        })

    }
}