作者:fengsh998
转载请注明出处
如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢!
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
}