Skip to content

Instantly share code, notes, and snippets.

@justdoit0823
Last active March 15, 2017 00:47
Show Gist options
  • Save justdoit0823/15aa68be7512da771d0f4fbaa1881bd9 to your computer and use it in GitHub Desktop.
Save justdoit0823/15aa68be7512da771d0f4fbaa1881bd9 to your computer and use it in GitHub Desktop.
//
// ViewController.swift
// SlideView
//
// Created by 余森彬 on 2017/3/10.
// Copyright © 2017年 余森彬. All rights reserved.
//
import CoreGraphics
import CoreText
import Foundation
import UIKit
class BackgroundAttributeView: UIView {
var text:NSAttributedString = {
var att = [NSFontAttributeName:UIFont(name:"Helvetica", size:20)!]
var text = NSMutableAttributedString(string: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis ullamco", attributes:att)
text.append(NSAttributedString(string: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", attributes: ["kBackgroundAttribute":UIColor.cyan]))
text.append(NSAttributedString(string: " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation", attributes:att))
return text
}()
override func draw(_ rect: CGRect) {
super.draw(rect)
var frameSetter = CTFramesetterCreateWithAttributedString(text)
var framePath = CGMutablePath()
framePath.addRect(self.bounds)
var ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), framePath, nil)
var frameRange = CTFrameGetVisibleStringRange(ctFrame)
var ctx = UIGraphicsGetCurrentContext()
ctx?.saveGState()
ctx?.textMatrix = CGAffineTransform.identity
ctx?.translateBy(x: 0, y: bounds.height)
ctx?.scaleBy(x: 1.0, y: -1.0)
var lines:NSArray = CTFrameGetLines(ctFrame)
var lineOrigins:[CGPoint] = [CGPoint](repeating: CGPoint.zero, count:lines.count)
CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), &lineOrigins)
var currentLineHeight:CGFloat = 0
var lineHeight:CGFloat = 0
for (lineIndex, line) in lines.enumerated() {
let lineOrigin = lineOrigins[lineIndex]
var runs:NSArray = CTLineGetGlyphRuns(line as! CTLine)
for run:CTRun in runs as! [CTRun] {
let stringRange = CTRunGetStringRange(run)
var ascent:CGFloat = 0
var descent:CGFloat = 0
var leading:CGFloat = 0
let typographicBounds = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), &ascent, &descent, &leading)
var xOffset:CGFloat = CTLineGetOffsetForStringIndex(line as! CTLine, stringRange.location, nil)
ctx?.textPosition = CGPoint(x: lineOrigin.x, y: lineOrigin.y + descent)
var currentLineHeight = ascent + descent + leading
if currentLineHeight > lineHeight {
lineHeight = currentLineHeight
}
var runBounds = CGRect(x: lineOrigin.x + xOffset, y: lineOrigin.y, width: CGFloat(typographicBounds), height: (ascent + descent))
var attributes:NSDictionary = CTRunGetAttributes(run)
var maybeColor = attributes.value(forKey: "kBackgroundAttribute") as! UIColor?
if let color = maybeColor {
let path = UIBezierPath(roundedRect: runBounds, cornerRadius: 3)
color.setFill()
path.fill()
}
CTRunDraw(run, ctx!, CFRangeMake(0, 0))
}
}
ctx?.restoreGState()
}
}
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var webView: UIWebView!
var leftSubView: UIView!
var rightSubView: UIView!
@IBAction func showView(_ sender: Any) {
let parentFrame = self.view.frame
let leftframe = CGRect(x: 0, y: 0, width: 0, height: parentFrame.height)
let rightframe = CGRect(x: parentFrame.width * 0.8, y: 0, width: parentFrame.width * 0.2, height: parentFrame.height)
let slideView = UIView(frame: leftframe)
let rightView = UIView(frame: rightframe)
let singleFingerTap = UITapGestureRecognizer(target: self, action: #selector(self.closeSlide))
rightView.addGestureRecognizer(singleFingerTap)
slideView.backgroundColor = UIColor(red: 2, green: 2, blue: 2, alpha: 0.8)
slideView.layer.shadowOpacity = 0.8
rightView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.95)
self.view.addSubview(slideView)
UIView.transition(with: slideView, duration: 1.0, options: UIViewAnimationOptions.curveEaseInOut, animations: ({slideView.frame = CGRect(x: 0, y: 0, width: parentFrame.width * 0.8, height: parentFrame.height)}))
self.view.insertSubview(rightView, belowSubview: slideView)
UIView.transition(with: slideView, duration: 0.5, options: UIViewAnimationOptions.curveEaseInOut, animations: ({rightView.alpha = 1}))
self.leftSubView = slideView
self.rightSubView = rightView
//NSAttributedString
NSHTMLTextDocumentType
//NSParagraphStyle
}
func loadHtmlText() {
// let html_text = "<html><head><style type='text/css'>div{background-color:#00FFFF;width:150px;height:150px;overflow: auto}</style></head><body>
// <p>如果元素中的内容超出了给定的宽度和高度属性,overflow 属性可以确定是否显示滚动条等行为。</p>
//
// <div>
// 这个属性定义溢出元素内容区的内容会如何处理。如果值为 scroll,不论是否需要,用户代理都会提供一种滚动机制。因此,有可能即使元素框中可以放下所有内容也会出现滚动条。默认值是 visible。
// </div>
// </body>
//
// </html>"
let html_text = "<html><meta charset='utf-8'>\n<head>\n<style type='text/css'>\ndiv {\nbackground-color:#00FFFF;\nwidth:10em;\nheight:10em;\ntext-overflow: scroll\n; margin: 10ex;}\n</style>\n</head>\n\n<body>\n<p>如果元素中的内容超出了给定的宽度和高度属性,overflow 属性可以确定是否显示滚动条等行为。</p>\n\n<div>\n这个属性定义溢出元素内容区的内容会如何处理。如果值为 scroll,不论是否需要,用户代理都会提供一种滚动机制。因此,有可能即使元素框中可以放下所有内容也会出现滚动条。默认值是 visible。\n</div>\n</body>\n\n</html>"
let html_pre_text = "<pre class=\"PROGRAMLISTING\" nodeIndex=\"76\">\nmytable.arraycolumn[4]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nmytable.two_d_column[17][34]\n$1[10:42]\n(arrayfunction(a,b))[42]\n</pre>"
let paraStyle = NSMutableParagraphStyle()
paraStyle.lineSpacing = 10
paraStyle.paragraphSpacing = 5
let shadow = NSShadow()
shadow.shadowBlurRadius = 5
shadow.shadowColor = UIColor.brown
shadow.shadowOffset = CGSize(width: 10, height: 20)
do{
let attrText = try NSMutableAttributedString(data: Data(Array(html_text.utf8)), options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
// attrText.setAttributes([NSShadowAttributeName: shadow], range: NSRange(location: 0, length: attrText.length))
self.textView.attributedText = attrText
}
catch {
print("exception")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//self.loadHtmlText()
let html_str = "<pre class=\"PROGRAMLISTING\" nodeIndex=\"76\">\nmytable.arraycolumn[4]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nmytable.two_d_column[17][34]\n$1[10:42]\n(arrayfunction(a,b))[42]\n</pre>"
let content_str = ""
let backView = BackgroundAttributeView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
self.view.addSubview(backView)
self.webView.loadHTMLString(content_str, baseURL: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func closeSlide(_ sender: UITapGestureRecognizer) {
//self.leftSubView?.isHidden = true
let parentFrame = self.view.frame
UIView.transition(with: self.leftSubView, duration: 1.0, options: UIViewAnimationOptions.curveEaseInOut, animations: ({self.leftSubView.frame = CGRect(x: 0, y: 0, width: 0, height: parentFrame.height)}))
UIView.transition(with: self.rightSubView, duration: 0.5, options: UIViewAnimationOptions.curveEaseInOut, animations: ({self.rightSubView.alpha = 0}))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment