首页 > 代码库 > Swift实战

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
    }