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 }