Swift实战

swift学习也快有一个月了。文章也写了不少。今天来发布一个小DEMO。当操刀练手了。

主要写一个小控件,实现功能是类拟IPHONE手机打开AppStore 中的详细信息中的内容,先显示一部分,点击更多时,再加载完成。

目前只对单文本字体作处理,对于富文本的并不行。因此作为swift的操刀之作,还算是处女作吧。。。。。

源码:

整个控件的源码在:http://download.csdn.net/detail/fengsh998/7552229

效果:

其中这个“更多“的位置可以自行调整,当点击更多时,就会展示全部:

核心代码:

  //more btn
    func drawMoreInRect(moreRect:CGRect)
    {
        var ctx = UIGraphicsGetCurrentContext();
        CGContextSaveGState(ctx);

        var raduis = CGRectGetHeight(moreRect) / 2.0

        var maxX = CGRectGetMaxX(moreRect)
        var minX = CGRectGetMinX(moreRect)
        var maxY = CGRectGetMaxY(moreRect)
        var minY = CGRectGetMinY(moreRect)

        CGContextMoveToPoint(ctx,minX,minY)
        CGContextAddArcToPoint(ctx,maxX,minY,maxX,maxY,raduis)
        CGContextAddArcToPoint(ctx,maxX,maxY,minX,maxY,raduis)
        CGContextAddArcToPoint(ctx,minX,maxY,minX,minY,raduis)
        CGContextAddArcToPoint(ctx,minX,minY,maxX,minY,raduis)

        CGContextClosePath(ctx)
        if selectedHightlight
        {
            CGContextSetRGBFillColor(ctx, 29/255.0, 158/255.0, 245/255.0, 1.0)
        }
        else
        {
            CGContextSetRGBFillColor(ctx, 104/255.0, 202/255.0, 248/255.0, 1.0)
        }

        CGContextDrawPath(ctx, kCGPathFill) //根据坐标绘制路径
        CGContextRestoreGState(ctx)
    }

    override func drawRect(rect:CGRect)
    {
        var attributedString = NSMutableAttributedString(string: self.text)
        let len = countElements(String(self.text))

        let fname = self.font.fontName

        //String convert to CFString
        //let cfstr : CFString = reinterpretCast(fname.withCString(getenv))

        let mfont = self.font

        var attributes = NSMutableDictionary()

        attributes.setObject(mfont,forKey:kCTFontAttributeName)

        attributedString.addAttributes(attributes,range:NSMakeRange(0,len))

        self.attributedText = attributedString;

        var framesetter = CTFramesetterCreateWithAttributedString(attributedString)

        var Path = CGPathCreateMutable()

        var rectWidth = self.bounds.size.width

        CGPathAddRect(Path, nil ,CGRectMake(0,0,rectWidth,CGFLOAT_MAX))

        var frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,0), Path, nil)

        var rows = CTFrameGetLines(frame)

        if let hasRows = rows?
        {
            //获取frame中的行数
            var numberOfLines = CFArrayGetCount(rows)
            //println("rows = \(numberOfLines)")

            var fontLineHeight = self.font.lineHeight

            var textOffset = self.font.ascender

            var ctx = UIGraphicsGetCurrentContext()
            CGContextSaveGState(ctx)
            //距左上位置设置
            CGContextTranslateCTM(ctx, 0, 0)
            CGContextSetTextMatrix(ctx, CGAffineTransformMakeScale(1,-1))

            for var lineNumber=0; lineNumber<numberOfLines; lineNumber++
            {
                var onlyline = CFArrayGetValueAtIndex(rows, lineNumber)
                var flush : Double = 0.0

                var onlycline :CTLine = reinterpretCast(onlyline)

                var penOffset = CTLineGetPenOffsetForFlush(onlycline, flush, rect.size.width)

                CGContextSetTextPosition(ctx, penOffset, textOffset);

                //println("第\(lineNumber)行\(onlycline)")
                //获取第onlycline行中的字形数
                //var nums = CTLineGetGlyphCount(onlycline)
                //println("本行的字符数\(nums)")

                if let mp = morepoint
                {
                    var posline = mp.row
                    var posclm = mp.column

                    var bool_lastline = (posline == numberOfLines - 1) ? true : false

                    if lineNumber == posline && !self.expand
                    {
                        var truncatedString = NSAttributedString(string: "\u2026")
                        var token = CTLineCreateWithAttributedString(truncatedString)

                        var range = CTLineGetStringRange(onlycline)
                        var maxlengthInline = range.length

                        posclm = min(posclm,maxlengthInline)

                        //获取onlycline中一黄有几个CTRun, 一般情况下,一行中只有一个CTRun
                        var runs = CTLineGetGlyphRuns(onlycline)
                        var runsNums = CFArrayGetCount(runs)

                        var rw = 0.0
                        var rh = 0.0
                        var rowx = 0.0
                        var rowy = 0.0
                        if runsNums > 0
                        {
                            //将COpaquePointer 转为CTRun
                            var run :CTRun = reinterpretCast(CFArrayGetValueAtIndex(runs, 0))
                            //println("run = \(run)")
                            var runrange = CFRange(location: 0,length:(posclm == 0) ? 1 : posclm )
                            //println("runrange = \(runrange.length)")
                            var runsrect = CTRunGetImageBounds(run, ctx, runrange)
                            //println("runsrect = \(runsrect)")
                            rw = min(runsrect.size.width,rectWidth-40)
                            rh = runsrect.size.height
                            rowx = runsrect.origin.x
                            rowy = runsrect.origin.y
                        }

                        var newline = CTLineCreateTruncatedLine(onlycline, rw, CTLineTruncationType.End, token)
                        CTLineDraw(newline, ctx)

                        var linerect = CGRectMake(rowx,rowy,0,0)
                        if newline
                        {
                            linerect = CTLineGetImageBounds(newline,ctx)
                        }
                        //println("本行文字占的rect\(linerect)")

                        //rh = min(rh,16)
                        //rh = max(rh,10)
                        rh = 16.0

                        moreBtnRect = CGRectMake(linerect.origin.x,
                            linerect.origin.y - rh + 3,40,rh)

                        self.drawMoreInRect(moreBtnRect!)

                        var moretextrect = CGRectMake(moreBtnRect!.origin.x + rh/2+3, moreBtnRect!.origin.y+2,
                            moreBtnRect!.size.width - rh, moreBtnRect!.size.height)
                        var moretext : NSString = "更多"
                        moretext.drawInRect(moretextrect, withFont: UIFont.systemFontOfSize(10))

                        break
                    }
                }

                CTLineDraw(onlycline, ctx)

                textOffset += fontLineHeight
            }//end for

            CGContextRestoreGState(ctx);

            var contentRect = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, round(textOffset-self.font.ascender))

            //println("contentRect = \(contentRect)")
            if contentRect.size.height > self.bounds.size.height
            {
                dispatch_async(dispatch_get_main_queue(), {
                    self.viewFrameChangeBlock(self,contentRect)
                    })
            }

        }//end if
    }

Swift实战

时间: 2024-08-28 12:58:05

Swift实战的相关文章

[swift实战入门]手把手教你编写2048(三)

上篇地址:swift实战入门之手把手教你编写2048(二) github地址:https://github.com/scarlettbai/2048.git. 今天给大家带来2048最后一篇,之前已经实现了向游戏区域中随机插入数字块,接下来要做的,就是当我们滑动屏幕时移动及合并数字块以及插入一个新的数字块.本篇的难点就是移动时的算法问题,首先来给大家讲一下算法. 2048的算法实现其实很简单,假如我们当前数字格的格式如下: | |4| | | | | |4| | |2| |2|2| |2| |

零基础Swift实战开发视频教程_从入门到精通

零基础Swift实战开发从入门到精通(4大项目实战.酷跑熊猫.百度音乐.足球游戏等)适合人群:初级课时数量:50课时更新程度:86%用到技术:Swift涉及项目:酷跑熊猫.百度音乐.足球游戏咨询qq:1840215592零基础Swift实战开发视频教程采用基础+项目的方式进行讲解,通过基础的学习,可以完全掌握Swift基本语法应用,并结合4个项目进行开发,学员能在最短的时间内掌握开发的各项技能. 零基础Swift实战开发从入门到精通详细查看:http://www.ibeifeng.com/goo

[swift实战入门]手把手教你编写2048(二)

上篇地址:swift实战入门之手把手教你编写2048(一) github地址:https://github.com/scarlettbai/2048.git. 上篇文章已经中已经把2048的游戏区块画好了,这篇来加入计分板以及往游戏面板中插入数字块 计分板同样作为一个view,我们新建一个ScoreView.swift文件,代码如下: import UIKit //这里协议的作用是方便别的类中调用计分板的scoreChanged方法 protocol ScoreProtocol{ func sc

IOS8开发视频教程之:基于Swift实战UI从入门到精通

IOS8开发视频教程之:基于Swift实战UI从入门到精通(5大项目.深入解析拉手团购项目)课程讲师:朱启文课程分类:IOS适合人群:初级课时数量:81课时用到技术:Swift.iOS8涉及项目:移动的图片案例.图片展示案例.汤姆猫案例.拉手团购案例.九宫格案例咨询QQ:1840215592 一.iOS8开发基于Swift实战UI初级课程移动的图片案例(共9课,完成9课)通过该案例,让大家掌握UIButton控件与UIImage区别使用,掌握IB连线的各类方法 tag使用,transform/f

Swift实战之2048小游戏

上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完善,就这么整理一下过程中一些值得记录的点吧. 用的Swift版本是2.0,原书中的Swift版本会低一些,所以实践起来有些地方语法并不一样. 一.开始页面   在程序的第一张页面(Main.storyboard)上,只放了一个“开始游戏”按钮,点击按钮,弹出一个提示对话框,确认后,进入游戏页面. 1

零基础Swift实战开发从入门到精通(4大项目实战、酷跑熊猫、百度音乐、足球游戏等)

第一部分:Swift基础语法 第1节:变量 第2节:常量 第3节:使用PlayRound编写Swift程序 第4节:类型检查与推断 第5节:类型别名 第6节:计算器 第二部分:字符和字符串 第1节:字符(Characters) 第2节:字符串-定义 第三部分:数据类型(DataType) 第1节:整型(int.Uint) 第2节:浮点数 第3节:Bool 第四部分:数据类型转换 第1节字符串转换数字类型 第2节数字类型转换字符串 第3节:数字类型之间转换 更多............ 项目实战一

Swift 实战随笔

翻看了国内好多的blog啊,要么太基础,要么太局部复杂,于是乎还是翻国外的东西比较干货: 找到了一个很好的官方的教程,比较精简,适合懂一部分又不懂一部分需要从实战中学习的孩纸. https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift 有兴趣的同学可以看看. 这一系列的blog就当翻译了,希望自己能坚持下去.

Swift实战-QQ在线音乐(第二版)

此版本使用百度音乐接口,原因是豆瓣接口很多歌曲没办法找到歌词. 此版本添加了歌词的显示.上一曲.下一曲的实现.歌曲列表指明当前歌曲. 下面来看一下实现过程>>> 一.项目准备: 百度音乐国语歌曲列表Api接口: http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.getSmartSongList&page_no=1&page_size=50&scene_id=42&

Swift实战-小QQ(第1章):QQ登录界面

1.新建小QQ项目 2.将所需用到的图片资源(resource)文件夹,添加到项目中.并新建一个登录页面:LoginViewController.swift 3.修改LoginViewController.swift代码为 import UIKit class LoginViewController: UIViewController { // } 4.将Main.storyboard的默认的view视图,关联为LoginViewController控制器,并拖控件进入view视图布局. 简单布