ʾÀý
#5£ºCAGradientLayer
CAGradientLayer¼ò»¯ÁË»ìºÏÁ½ÖÖ»ò¸ü¶àÑÕÉ«µÄ¹¤×÷£¬ÓÈÆäÊÊÓÃÓÚ±³¾°¡£ÒªÅäÖý¥±äÉ«£¬ÄãÐèÒª·ÖÅäÒ»¸öCGColorÊý×飬ÒÔ¼°±êʶ½¥±äͼ²ãÆðÖ¹µãµÄstartPointºÍendPoint¡£
×¢Ò⣺startPointºÍendPoint²¢²»ÊÇÃ÷È·µÄµã£¬¶øÊÇÓõ¥Î»×ø±ê¿Õ¼ä¶¨Ò壬ÔÚ»æÖÆÊ±Ó³É䵽ͼ²ã±ß½ç¡£Ò²¾ÍÊÇ˵xֵΪ1±íʾµãÔÚͼ²ãÓÒ±ßÔµ£¬yֵΪ1±íʾµãÔÚͼ²ãϱßÔµ¡£
CAGradientLayer°üº¬typeÊôÐÔ£¬Ëä˵¸ÃÊôÐÔÖ»ÓÐkCAGradientLayerAxialÒ»¸öÑ¡Ôñ£¬ÓÉÊý×éÖеĸ÷ÑÕÉ«²úÉúÏßÐÔ¹ý¶É½¥±ä¡£
¾ßÌ庬ÒåÊǽ¥±ä¹ý¶ÉÑØstartPointµ½endPointµÄÏòÁ¿A·½Ïò²úÉú£¬ÉèBÓëA´¹Ö±£¬Ôò¸÷ÌõBƽÐÐÏßÉϵÄËùÓеãÑÕÉ«Ïàͬ¡£

´ËÍ⣬locationsÊôÐÔ¿ÉÒÔʹÓÃÒ»¸öÊý×é£¨ÔªËØÈ¡Öµ·¶Î§0µ½1£©£¬Ö¸¶¨½¥±äͼ²ã²ÎÕÕcolors˳ÐòÈ¡ÓÃÏÂÒ»¸ö¹ý¶ÉµãÑÕÉ«µÄλÖá£
δÉ趨ʱĬÈÏ»áÆ½¾ù·ÖÅä¹ý¶Éµã¡£Ò»µ©É趨¾Í±ØÐëÓëcolorsµÄÊýÁ¿±£³ÖÒ»Ö£¬·ñÔò»á³ö´í¡£ :[
ÏÂÃæÊÇ´´½¨½¥±äͼ²ãµÄÀý×Ó£º
let gradientLayer = CAGradientLayer() gradientLayer.frame = someView.bounds gradientLayer.colors = [cgColorForRed(209.0, green: 0.0, blue: 0.0), cgColorForRed(255.0, green: 102.0, blue: 34.0), cgColorForRed(255.0, green: 218.0, blue: 33.0), cgColorForRed(51.0, green: 221.0, blue: 0.0), cgColorForRed(17.0, green: 51.0, blue: 204.0), cgColorForRed(34.0, green: 0.0, blue: 102.0), cgColorForRed(51.0, green: 0.0, blue: 68.0)] gradientLayer.startPoint = CGPoint(x: 0, y: 0) gradientLayer.endPoint = CGPoint(x: 0, y: 1) someView.layer.addSublayer(gradientLayer) |
func cgColorForRed(red: CGFloat, green: CGFloat, blue: CGFloat) -> AnyObject { return UIColor(red: red/255.0, green: green/255.0, blue: blue/255.0, alpha: 1.0).CGColor as AnyObject } |
ÉÏÊö´úÂë´´½¨Ò»¸ö½¥±äͼ²ã£¬¿ò¼ÜÉèΪsomeView±ß½ç£¬Ö¸¶¨ÑÕÉ«Êý×飬ÉèÖÃÆðÖ¹µã£¬Ìí¼Óͼ²ãµ½ÊÓͼ½á¹¹Ê÷¡£Ð§¹ûÈçÏ£º

Îå²ÊçÍ·×£¬æ±×ÏæÌºì£¡
ͼ²ãÑÝʾӦÓÃÖУ¬Äã¿ÉÒÔËæÒâÐÞ¸ÄÆðÖ¹µã¡¢ÑÕÉ«ºÍ¹ý¶Éµã£º

ʾÀý #6£ºCAReplicatorLayer
CAReplicatorLayerÄܹ»ÒÔÌØ¶¨´ÎÊý¸´ÖÆÍ¼²ã£¬¿ÉÒÔÓÃÀ´´´½¨Ò»Ð©ºÜ°ôµÄЧ¹û¡£
ÿ¸öͼ²ã¸´¼þµÄÑÕÉ«ºÍλÖö¼¿ÉÒԸ͝£¬¶øÇÒ¿ÉÒÔÔÚ×ܸ´ÖÆÍ¼²ãÖ®ºóÑÓ³Ù»æÖÆ£¬ÓªÔìÒ»ÖÖ¶¯»Ð§¹û¡£»¹¿ÉÒÔÀûÓÃÉî¶È£¬´´ÔìÈýάЧ¹û¡£¾Ù¸öÀý×Ó
// 1 let replicatorLayer = CAReplicatorLayer() replicatorLayer.frame = someView.bounds // 2 replicatorLayer.instanceCount = 30 replicatorLayer.instanceDelay = CFTimeInterval(1 / 30.0) replicatorLayer.preservesDepth = false replicatorLayer.instanceColor = UIColor.whiteColor().CGColor // 3 replicatorLayer.instanceRedOffset = 0.0 replicatorLayer.instanceGreenOffset = -0.5 replicatorLayer.instanceBlueOffset = -0.5 replicatorLayer.instanceAlphaOffset = 0.0 // 4 let angle = Float(M_PI * 2.0) / 30 replicatorLayer.instanceTransform = CATransform3DMakeRotation(CGFloat(angle), 0.0, 0.0, 1.0) someView.layer.addSublayer(replicatorLayer) // 5 let instanceLayer = CALayer() let layerWidth: CGFloat = 10.0 let midX = CGRectGetMidX(someView.bounds) - layerWidth / 2.0 instanceLayer.frame = CGRect(x: midX, y: 0.0, width: layerWidth, height: layerWidth * 3.0) instanceLayer.backgroundColor = UIColor.whiteColor().CGColor replicatorLayer.addSublayer(instanceLayer) // 6 let fadeAnimation = CABasicAnimation(keyPath: "opacity") fadeAnimation.fromValue = 1.0 fadeAnimation.toValue = 0.0 fadeAnimation.duration = 1 fadeAnimation.repeatCount = Float(Int.max) // 7 instanceLayer.opacity = 0.0 instanceLayer.addAnimation(fadeAnimation, forKey: "FadeAnimation") |
ÒÔÉÏ´úÂ룺
´´½¨Ò»¸öCAReplicatorLayerʵÀý£¬Éè¿ò¼ÜΪsomeView±ß½ç¡£
Éè¸´ÖÆÍ¼²ãÊýinstanceCountºÍ»æÖÆÑÓ³Ù£¬Éèͼ²ãΪ2D£¨preservesDepth = false£©£¬ÊµÀýÑÕɫΪ°×É«¡£
ÎªÂ½ÐøµÄʵÀý¸´¼þÉèÖÃRGBÑÕɫƫ²îÖµ£¨Ä¬ÈÏΪ0£¬¼´ËùÓи´¼þ±£³ÖÑÕÉ«²»±ä£©£¬²»¹ýÕâÀïʵÀý³õʼÑÕɫΪ°×É«£¬¼´RGB¶¼Îª1.0£¬ËùÒÔÆ«²îÖµÉèºìɫΪ0£¬ÂÌÉ«ºÍÀ¶É«ÎªÏàͬ¸ºÊý»áʹÆäÖð½¥ÏÖ³öºìÉ«£¬alpha͸Ã÷¶ÈÆ«²îÖµµÄ±ä»¯Ò²Óë´ËÀàËÆ£¬Õë¶ÔÂ½ÐøµÄʵÀý¸´¼þ¡£
´´½¨Ðýת±ä»»£¬Ê¹µÃʵÀý¸´¼þ°´Ò»¸öÔ²ÅÅÁС£
´´½¨¹©¸´ÖÆÍ¼²ãʹÓõÄʵÀýͼ²ã£¬ÉèÖÿò¼Ü£¬Ê¹µÚÒ»¸öʵÀýÔÚsomeView±ß½ç¶¥¶ËˮƽÖÐÐÄ´¦»æÖÆ£¬ÁíÍâÉèÖÃʵÀýÑÕÉ«£¬°ÑʵÀýͼ²ãÌí¼Óµ½¸´ÖÆÍ¼²ã¡£
´´½¨Ò»¸ö͸Ã÷¶ÈÓÉ1£¨²»Í¸Ã÷£©¹ý¶ÉΪ0£¨Í¸Ã÷£©µÄµ³ö¶¯»¡£
ÉèʵÀýͼ²ã͸Ã÷¶ÈΪ0£¬Ê¹µÃÿ¸öʵÀýÔÚ»æÖƺ͸ıäÑÕÉ«Óëalphaǰ±£³Ö͸Ã÷¡£
Õâ¶Î´úÂë»áʵÏÖÕâÑùµÄ¶«Î÷£º

ͼ²ãÑÝʾӦÓÃÖУ¬Äã¿ÉÒԸ͝ÕâЩÊôÐÔ£º

ʾÀý #7£ºCATiledLayer
CATiledLayerÒÔͼ¿é£¨tile£©Îªµ¥Î»Òì²½»æÖÆÍ¼²ãÄÚÈÝ£¬¶Ô³¬´ó³ß´çͼƬ»òÕßÖ»ÄÜÔÚÊÓͼÖÐÏÔʾһС²¿·ÖµÄÄÚÈÝЧ¹û°ÎȺ£¬ÒòΪ²»ÓðÑÄÚÈÝÍêÈ«ÔØÈëÄÚ´æ¾Í¿ÉÒÔ¿´µ½ÄÚÈÝ¡£
´¦Àí»æÖÆÓм¸ÖÖ·½·¨£¬Ò»ÖÖÊÇÖØÐ´UIView£¬Ê¹ÓÃCATiledLayer»æÖÆÍ¼¿éÌî³äÊÓͼ±³¾°£¬ÈçÏ£º
// In ViewController.swift import UIKit class ViewController: UIViewController { // 1 @IBOutlet weak var tiledBackgroundView: TiledBackgroundView! } // In TiledBackgroundView.swift import UIKit class TiledBackgroundView: UIView { let sideLength = CGFloat(50.0) // 2 override class func layerClass() -> AnyClass { return CATiledLayer.self } // 3 required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) srand48(Int(NSDate().timeIntervalSince1970)) let layer = self.layer as CATiledLayer let scale = UIScreen.mainScreen().scale layer.contentsScale = scale layer.tileSize = CGSize(width: sideLength * scale, height: sideLength * scale) } // 4 override func drawRect(rect: CGRect) { let context = UIGraphicsGetCurrentContext() var red = CGFloat(drand48()) var green = CGFloat(drand48()) var blue = CGFloat(drand48()) CGContextSetRGBFillColor(context, red, green, blue, 1.0) CGContextFillRect(context, rect) } } |
´úÂë½âÊÍ£º
tiledBackgroundViewλÓÚ (150, 150) £¬¿í¸ß¾ùΪ300¡£
ÖØÐ´layerClass()£¬Áî¸ÃÊÓͼ´´½¨µÄͼ²ãʵÀýΪCATiledLayer¡£
ÉèÖÃrand48()µÄËæ»úÊýÖÖ×Ó£¬ÓÃÓÚÔÚdrawRect()ÖÐÉú³ÉËæ»úÑÕÉ«¡£CATiledLayerÀàÐÍת»»£¬Ëõ·Åͼ²ãÄÚÈÝ£¬ÉèÖÃͼ¿é³ß´ç£¬ÊÊÓ¦ÆÁÄ»¡£
ÖØÐ´drawRect()£¬ÒÔËæ»úÉ«¿éÌî³äÊÓͼ¡£
´úÂë»æÖÆ6¡Á6Ëæ»úÉ«¿é·½¸ñ£¬×îÖÕЧ¹ûÈçÏ£º

ͼ²ãÑÝʾӦÓÃÖгý´ËÖ®Í⻹¿ÉÒÔÔÚͼ²ã±³¾°ÉÏ»æÖƹ켣£º

ÔÚÊÓͼÖзŴóʱ£¬ÉÏÊö½ØÍ¼ÖеÄÐÇÐÇͼ°¸»á±äµÃÄ£ºý£º

²úÉúÄ£ºýµÄ¸ùÔ´ÊÇͼ²ãµÄϸ½Ú²ã´Î£¨level of detail£¬¼ò³ÆLOD£©£¬CATiledLayerÓÐÁ½¸öÏà¹ØÊôÐÔ£ºlevelsOfDetailºÍlevelsOfDetailBias¡£
levelsOfDetail¹ËÃû˼Ò壬ָͼ²ãά»¤µÄLODÊýÄ¿£¬Ä¬ÈÏֵΪ1£¬Ã¿½øÒ»¼¶»á¶Ôǰһ¼¶·Ö±æÂʵÄÒ»°ë½øÐлº´æ£¬Í¼²ãµÄlevelsOfDetail×î´óÖµ£¬Ò²¾ÍÊÇ×îµ×²ãϸ½Ú£¬¶ÔÓ¦ÖÁÉÙÒ»¸öÏñËØµã¡£
¶ølevelsOfDetailBiasÖ¸µÄÊǸÃͼ²ã»º´æµÄ·Å´óLODÊýÄ¿£¬Ä¬ÈÏΪ0£¬¼´²»»á¶îÍ⻺´æ·Å´ó²ã´Î£¬Ã¿½øÒ»¼¶»á¶Ôǰһ¼¶Á½±¶·Ö±æÂʽøÐлº´æ¡£
ÀýÈ磬ÉèÉÏÊö·Ö¿éͼ²ãµÄlevelsOfDetailBiasΪ5»á»º´æ2x¡¢4x¡¢8x¡¢16xºÍ32xµÄ·Å´ó²ã´Î£¬·Å´óµÄͼ²ãЧ¹ûÈçÏ£º

²»´í°É£¿±ð׿±£¬»¹Ã»½²ÍêÄØ¡£
CATiledLayer²Ãµ¶£¬Âò²»Á˳Կ÷£¬Âò²»ÁËÉϵ±£¬Ö»Òª998¡£¨Òë×¢£º´Ë´¦ÄÚÈÝÉÔ×÷±¾µØ»¯´¦Àí£¬ÔÎÄÍæµÄÊÇ1978ÄêÃÀ¹úGinsuµ¶¾ßµÄ¹££¬¿°³ÆÑ¯¼ÛÐ͵çÊÓ¹ºÎï¹ã¸æµÄÍò¶ñÖ®Ô´¡££©
:]
¿ª¸öÍæÐ¦¡£CATiledLayer»¹ÓÐÒ»¸ö¸üʵÓõŦÄÜ£ºÒì²½»æÖÆÍ¼¿é£¬±ÈÈçÔÚ¹ö¶¯ÊÓͼÖÐÏÔʾһÕų¬´óͼƬ¡£
ÔÚÓû§¹ö¶¯»ÃæÊ±£¬ÒªÈ÷ֿéͼ²ãÖªµÀÄÄЩͼ¿éÐèÒª»æÖÆ£¬Ð´´úÂëÔÚËùÄÑÃ⣬²»¹ý»»À´ÐÔÄÜÌáÉýÒ²ÖµÁË¡£
ͼ²ãÑÝʾӦÓõÄUIImage+TileCutter.swiftÖаüº¬Ò»¸öUIImageÀ©Õ¹£¬½Ì³Ì±à×ë×é³ÉÔ±Nick
LockwoodÔÚÖø×÷iOS Core Animation: Advanced TechniquesµÄÒ»¸öÖÕ¶ËÓ¦ÓóÌÐòÖÐÀûÓÃÁËÕâ¶Î´úÂë¡£
´úÂëµÄÖ°ÔðÊǰÑÔͼƬ²ð·Ö³ÉÖ¸¶¨³ß´çµÄ·½¿é£¬°´ÐÐÁÐλÖÃÃüÃûͼ¿é£¬±ÈÈçµÚÈýÐÐµÚÆßÁеÄͼ¿éwindingRoad62.png£¨Ë÷Òý´ÓÁ㿪ʼ£©¡£

ÓÐÁËÕâЩͼ¿é£¬ÎÒÃÇ¿ÉÒÔ×Ô¶¨ÒåÒ»¸öUIView×ÓÀ࣬»æÖÆ·Ö¿éͼ²ã£º
mport UIKit class TilingViewForImage: UIView { // 1 let sideLength = CGFloat(640.0) let fileName = "windingRoad" let cachesPath = NSSearchPathForDirectoriesInDomains
(.CachesDirectory, .UserDomainMask, true)[0] as String // 2 override class func layerClass() -> AnyClass { return CATiledLayer.self } // 3 required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let layer = self.layer as CATiledLayer layer.tileSize = CGSize(width: sideLength, height: sideLength) } // 4 override func drawRect(rect: CGRect) { let firstColumn = Int(CGRectGetMinX(rect) / sideLength) let lastColumn = Int(CGRectGetMaxX(rect) / sideLength) let firstRow = Int(CGRectGetMinY(rect) / sideLength) let lastRow = Int(CGRectGetMaxY(rect) / sideLength) for row in firstRow...lastRow { for column in firstColumn...lastColumn { if let tile = imageForTileAtColumn(column, row: row) { let x = sideLength * CGFloat(column) let y = sideLength * CGFloat(row) let point = CGPoint(x: x, y: y) let size = CGSize(width: sideLength, height: sideLength) var tileRect = CGRect(origin: point, size: size) tileRect = CGRectIntersection(bounds, tileRect) tile.drawInRect(tileRect) } } } } func imageForTileAtColumn(column: Int, row: Int) -> UIImage? { let filePath = "\(cachesPath)/\(fileName)_\(column)_\(row)" return UIImage(contentsOfFile: filePath) } } |
ÒÔÉÏ´úÂ룺
´´½¨ÊôÐÔ£¬·Ö±ðÊÇͼ¿é±ß³¤¡¢ÔͼÎļþÃû¡¢¹©TileCutterÀ©Õ¹±£´æÍ¼¿éµÄ»º´æÎļþ¼Ð·¾¶¡£
ÖØÐ´layerClass()·µ»ØCATiledLayer¡£
ʵÏÖinit(_:)£¬°ÑÊÓͼµÄͼ²ãת»»Îª·Ö¿éͼ²ã£¬ÉèÖÃͼ¿é´óС¡£×¢Òâ´Ë´¦²»±ØÉèÖÃcontentsScaleÊÊÅäÆÁÄ»£¬ÒòΪÊÇÖ±½ÓÐÞ¸ÄÊÓͼ×ÔÉíµÄͼ²ã£¬¶ø²»ÊÇÊÖ¶¯´´½¨×Óͼ²ã¡£
ÖØÐ´drawRect()£¬°´ÐÐÁлæÖƸ÷¸öͼ¿é¡£
ÏñÕâÑù£¬Ôͼ´óСµÄ×Ô¶¨ÒåÊÓͼ¾Í¿ÉÒÔÈû½øÒ»¸ö¹ö¶¯ÊÓͼ£º

¶à¿÷CATiledLayer£¬¹ö¶¯5120 x 3200µÄ´óͼҲ»áÕâ°ã˳»¬£º

ÈçÄãËù¼û£¬¿ìËÙ¹ö¶¯Ê±»æÖÆÍ¼¿éµÄ¹ý³Ì»¹ÊǺÜÃ÷ÏÔ£¬Äã¿ÉÒÔÀûÓøüСµÄ·Ö¿é£¨ÉÏÊöÀý×ÓÖзֿéΪ640 x 640£©£¬»òÕß×Ô¼º´´½¨Ò»¸öCATiledLayer×ÓÀà£¬ÖØÐ´fadeDuration()·µ»Ø0£º
class TiledLayer: CATiledLayer { override class func fadeDuration() -> CFTimeInterval { return 0.0 } } |
ʾÀý #8£ºCAShapeLayer
CAShapeLayerÀûÓÿÉËõ·ÅµÄʸÁ¿Â·¾¶½øÐлæÖÆ£¬»æÖÆËٶȱÈʹÓÃͼƬ¿ìºÜ¶à£¬»¹ÓиöºÃ´¦ÊDz»Ó÷ֱðÌṩ³£¹æ¡¢@2xºÍ@3x°æ±¾µÄͼƬ£¬ºÃÓá£
ÁíÍ⻹Óи÷ÖÖÊôÐÔ£¬ÈÃÄã¿ÉÒÔ×Ô¶¨Ïß´Ö¡¢ÑÕÉ«¡¢Ðéʵ¡¢ÏßÌõ½ÓºÏ·½Ê½¡¢±ÕºÏÏßÌõÊÇ·ñÐγɱպÏÇøÓò£¬»¹ÓбպÏÇøÓòÒªÌî³äºÎÖÖÑÕÉ«µÈ¡£¾ÙÀýÈçÏÂ
import UIKit class ViewController: UIViewController { @IBOutlet weak var someView: UIView! // 1 let rwColor = UIColor(red: 11/255.0, green: 86/255.0, blue: 14/255.0, alpha: 1.0) let rwPath = UIBezierPath() let rwLayer = CAShapeLayer() // 2 func setUpRWPath() { rwPath.moveToPoint(CGPointMake(0.22, 124.79)) rwPath.addLineToPoint(CGPointMake(0.22, 249.57)) rwPath.addLineToPoint(CGPointMake(124.89, 249.57)) rwPath.addLineToPoint(CGPointMake(249.57, 249.57)) rwPath.addLineToPoint(CGPointMake(249.57, 143.79)) rwPath.addCurveToPoint(CGPointMake(249.37, 38.25),
controlPoint1: CGPointMake(249.57, 85.64), controlPoint2: CGPointMake(249.47, 38.15)) rwPath.addCurveToPoint(CGPointMake(206.47, 112.47),
controlPoint1: CGPointMake(249.27, 38.35), controlPoint2: CGPointMake(229.94, 71.76)) rwPath.addCurveToPoint(CGPointMake(163.46, 186.84),
controlPoint1: CGPointMake(182.99, 153.19), controlPoint2: CGPointMake(163.61, 186.65)) rwPath.addCurveToPoint(CGPointMake(146.17, 156.99),
controlPoint1: CGPointMake(163.27, 187.03), controlPoint2: CGPointMake(155.48, 173.59)) rwPath.addCurveToPoint(CGPointMake(128.79, 127.08),
controlPoint1: CGPointMake(136.82, 140.43), controlPoint2: CGPointMake(129.03, 126.94)) rwPath.addCurveToPoint(CGPointMake(109.31, 157.77),
controlPoint1: CGPointMake(128.59, 127.18), controlPoint2: CGPointMake(119.83, 141.01)) rwPath.addCurveToPoint(CGPointMake(89.83, 187.86),
controlPoint1: CGPointMake(98.79, 174.52), controlPoint2: CGPointMake(90.02, 188.06)) rwPath.addCurveToPoint(CGPointMake(56.52, 108.28),
controlPoint1: CGPointMake(89.24, 187.23), controlPoint2: CGPointMake(56.56, 109.11)) rwPath.addCurveToPoint(CGPointMake(64.02, 102.25),
controlPoint1: CGPointMake(56.47, 107.75), controlPoint2: CGPointMake(59.24, 105.56)) rwPath.addCurveToPoint(CGPointMake(101.42, 67.57),
controlPoint1: CGPointMake(81.99, 89.78), controlPoint2: CGPointMake(93.92, 78.72)) rwPath.addCurveToPoint(CGPointMake(108.38, 30.65),
controlPoint1: CGPointMake(110.28, 54.47), controlPoint2: CGPointMake(113.01, 39.96)) rwPath.addCurveToPoint(CGPointMake(10.35, 0.41),
controlPoint1: CGPointMake(99.66, 13.17), controlPoint2: CGPointMake(64.11, 2.16)) rwPath.addLineToPoint(CGPointMake(0.22, 0.07)) rwPath.addLineToPoint(CGPointMake(0.22, 124.79)) rwPath.closePath() } // 3 func setUpRWLayer() { rwLayer.path = rwPath.CGPath rwLayer.fillColor = rwColor.CGColor rwLayer.fillRule = kCAFillRuleNonZero rwLayer.lineCap = kCALineCapButt rwLayer.lineDashPattern = nil rwLayer.lineDashPhase = 0.0 rwLayer.lineJoin = kCALineJoinMiter rwLayer.lineWidth = 1.0 rwLayer.miterLimit = 10.0 rwLayer.strokeColor = rwColor.CGColor } override func viewDidLoad() { super.viewDidLoad() // 4 setUpRWPath() setUpRWLayer() someView.layer.addSublayer(rwLayer) } } |
´úÂë½âÊÍ£º
´´½¨ÑÕÉ«¡¢Â·¾¶¡¢Í¼ÐÎͼ²ã¶ÔÏó¡£
»æÖÆÍ¼ÐÎͼ²ã·¾¶¡£Èç¹û²»Ï²»¶±àдÉúÓ²µÄ»æÍ¼´úÂëµÄ»°£¬Äã¿ÉÒÔ³¢ÊÔPaintCodeÕâ¿îÈí¼þ£¬¿ÉÒÔÀûÓüò±ãµÄ¹¤¾ß½øÐпÉÊÓ»¯»æÖÆ£¬Ö§³Öµ¼ÈëÏÖÓеÄʸÁ¿Í¼£¨SVG£©ºÍPhotoshop£¨PSD£©Îļþ£¬²¢×Ô¶¯Éú³É´úÂë¡£
ÉèÖÃͼÐÎͼ²ã¡£Â·¾¶ÉèΪµÚ¶þ²½ÖлæÖƵÄCGPath·¾¶£¬Ìî³äÉ«ÉèΪµÚÒ»²½Öд´½¨µÄCGColorÑÕÉ«£¬Ìî³ä¹æÔòÉèΪ·ÇÁ㣨non-zero£©£¬¼´Ä¬ÈÏÌî³ä¹æÔò¡£
Ìî³ä¹æÔò¹²ÓÐÁ½ÖÖ£¬ÁíÒ»ÖÖÊÇÆæÅ¼£¨even-odd£©¡£²»¹ýʾÀý´úÂëÖеÄͼÐÎûÓÐÏཻ·¾¶£¬Á½ÖÖÌî³ä¹æÔòµÄ½á¹û²¢ÎÞ²îÒì¡£
·ÇÁã¹æÔò¼Ç´Ó×óµ½Óҵķ¾¶Îª+1£¬´ÓÓÒµ½×óµÄ·¾¶Îª-1£¬ÀÛ¼ÓËùÓз¾¶Öµ£¬Èô×ܺʹóÓÚÁ㣬ÔòÌî³ä·¾¶Î§³ÉµÄͼÐΡ£
´Ó½á¹ûÉÏÀ´½²£¬·ÇÁã¹æÔò»áÌî³äͼÐÎÄÚ²¿ËùÓеĵ㡣
ÆæÅ¼¹æÔò¼ÆËãΧ³ÉͼÐεÄ·¾¶½»²æÊý£¬Èô½á¹ûÎªÆæÊýÔòÌî³ä¡£ÕâÑù½²ÓÐЩ»Þɬ£¬»¹ÊÇÓÐͼÓÐÕæÏࣺ
ÓÒͼΧ³ÉÖмäÎå±ßÐεÄ·¾¶½»²æÊýΪżÊý£¬¹ÊÖмäûÓÐÌî³ä£¬¶øÎ§³Éÿ¸öÈý½ÇµÄ·¾¶½»²æÊýÎªÆæÊý£¬¹ÊÈý½Ç²¿·ÖÌî³äÑÕÉ«¡£

µ÷Ó÷¾¶»æÖƺÍͼ²ãÉèÖôúÂ룬²¢°Ñͼ²ãÌí¼Óµ½ÊÓͼ½á¹¹Ê÷¡£
ÉÏÊö´úÂë»æÖÆraywenderlich.comµÄͼ±ê£º

˳±ã¿´¿´Ê¹ÓÃPaintCodeµÄЧ¹ûͼ£º

ͼ²ãÑÝʾӦÓÃÖУ¬Äã¿ÉÒÔËæÒâÐ޸ĺܶàCAShapeLayerÊôÐÔ£º

×¢£ºÎÒÃÇÏÈÌø¹ýÑÝʾӦÓÃÖеÄÏÂÒ»¸öʾÀý£¬ÒòΪCAEAGLLayer¶àÉÙÏÔµÃÓÐЩ¹ýʱÁË£¬iOS 8 Metal¿ò¼ÜÓиüÏȽøµÄCAMetalLayer¡£ÔÚ´ËÍÆ¼öiOS
8 MetalÈëÃŽ̡̳£
ʾÀý #9£ºCATransformLayer
CATransformLayer²»ÏñÆäËûͼ²ãÀàÒ»Ñù°Ñ×Óͼ²ã½á¹¹Æ½Ã滯£¬¹ÊÊÊÒË»æÖÆ3D½á¹¹¡£±ä»»Í¼²ã±¾ÖÊÉÏÊÇÒ»¸öͼ²ãÈÝÆ÷£¬Ã¿¸ö×Óͼ²ã¶¼¿ÉÒÔÓ¦ÓÃ×Ô¼ºµÄ͸Ã÷¶ÈºÍ¿Õ¼ä±ä»»£¬¶øÆäËûäÖȾͼ²ãÊôÐÔ£¨Èç±ß¿í¡¢ÑÕÉ«£©»á±»ºöÂÔ¡£
±ä»»Í¼²ã±¾Éí²»Ö§³Öµã»÷²âÊÔ£¬ÒòΪÎÞ·¨Ö±½ÓÔÚ´¥ÃþµãºÍÆ½Ãæ×ø±ê¿Õ¼ä½¨Á¢Ó³É䣬²»¹ýÆäÖеÄ×Óͼ²ã¿ÉÒÔÏìÓ¦µã»÷²âÊÔ£¬ÀýÈ磺
import UIKit class ViewController: UIViewController { @IBOutlet weak var someView: UIView! // 1 let sideLength = CGFloat(160.0) var redColor = UIColor.redColor() var orangeColor = UIColor.orangeColor() var yellowColor = UIColor.yellowColor() var greenColor = UIColor.greenColor() var blueColor = UIColor.blueColor() var purpleColor = UIColor.purpleColor() var transformLayer = CATransformLayer() // 2 func setUpTransformLayer() { var layer = sideLayerWithColor(redColor) transformLayer.addSublayer(layer) layer = sideLayerWithColor(orangeColor) var transform = CATransform3DMakeTranslation(sideLength / 2.0, 0.0, sideLength / -2.0) transform = CATransform3DRotate(transform, degreesToRadians(90.0), 0.0, 1.0, 0.0) layer.transform = transform transformLayer.addSublayer(layer) layer = sideLayerWithColor(yellowColor) layer.transform = CATransform3DMakeTranslation(0.0, 0.0, -sideLength) transformLayer.addSublayer(layer) layer = sideLayerWithColor(greenColor) transform = CATransform3DMakeTranslation(sideLength / -2.0, 0.0, sideLength / -2.0) transform = CATransform3DRotate(transform, degreesToRadians(90.0), 0.0, 1.0, 0.0) layer.transform = transform transformLayer.addSublayer(layer) layer = sideLayerWithColor(blueColor) transform = CATransform3DMakeTranslation(0.0, sideLength / -2.0, sideLength / -2.0) transform = CATransform3DRotate(transform, degreesToRadians(90.0), 1.0, 0.0, 0.0) layer.transform = transform transformLayer.addSublayer(layer) layer = sideLayerWithColor(purpleColor) transform = CATransform3DMakeTranslation(0.0, sideLength / 2.0, sideLength / -2.0) transform = CATransform3DRotate(transform, degreesToRadians(90.0), 1.0, 0.0, 0.0) layer.transform = transform transformLayer.addSublayer(layer) transformLayer.anchorPointZ = sideLength / -2.0 applyRotationForXOffset(16.0, yOffset: 16.0) } // 3 func sideLayerWithColor(color: UIColor) -> CALayer { let layer = CALayer() layer.frame = CGRect(origin: CGPointZero, size: CGSize(width: sideLength, height: sideLength)) layer.position = CGPoint(x: CGRectGetMidX(someView.bounds), y: CGRectGetMidY(someView.bounds)) layer.backgroundColor = color.CGColor return layer } func degreesToRadians(degrees: Double) -> CGFloat { return CGFloat(degrees * M_PI / 180.0) } // 4 func applyRotationForXOffset(xOffset: Double, yOffset: Double) { let totalOffset = sqrt(xOffset * xOffset + yOffset * yOffset) let totalRotation = CGFloat(totalOffset * M_PI / 180.0) let xRotationalFactor = CGFloat(totalOffset) / totalRotation let yRotationalFactor = CGFloat(totalOffset) / totalRotation let currentTransform = CATransform3DTranslate(transformLayer.sublayerTransform, 0.0, 0.0, 0.0) let rotationTransform = CATransform3DRotate(transformLayer.sublayerTransform, totalRotation, xRotationalFactor * currentTransform.m12 - yRotationalFactor * currentTransform.m11, xRotationalFactor * currentTransform.m22 - yRotationalFactor * currentTransform.m21, xRotationalFactor * currentTransform.m32 - yRotationalFactor * currentTransform.m31) transformLayer.sublayerTransform = rotationTransform } // 5 override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { if let location = touches.anyObject()?.locationInView(someView) { for layer in transformLayer.sublayers { if let hitLayer = layer.hitTest(location) { println("Transform layer tapped!") break } } } } override func viewDidLoad() { super.viewDidLoad() // 6 setUpTransformLayer() someView.layer.addSublayer(transformLayer) } } |
ÉÏÊö´úÂë½âÊÍ£º
´´½¨ÊôÐÔ£¬·Ö±ðΪÁ¢·½ÌåµÄ±ß³¤¡¢Ã¿¸öÃæµÄÑÕÉ«£¬»¹ÓÐÒ»¸ö±ä»»Í¼²ã¡£
´´½¨Áù¸öÃæ£¬ÐýתºóÌí¼Óµ½±ä»»Í¼²ã£¬¹¹³ÉÁ¢·½Ì壬ȻºóÉèÖñ任ͼ²ãµÄzÖáêµã£¬ÐýתÁ¢·½Ì壬½«ÆäÌí¼Óµ½ÊÓͼ½á¹¹Ê÷¡£
¸¨Öú´úÂ룬ÓÃÀ´´´½¨Ö¸¶¨ÑÕÉ«µÄÃæ£¬»¹ÓнǶȺͻ¡¶ÈµÄת»»¡£Ôڱ任´úÂëÖÐÀûÓû¡¶Èת»»º¯ÊýÔÚijÖ̶ֳÈÉÏ¿ÉÒÔÔö¼Ó´úÂë¿É¶ÁÐÔ¡£
:]
»ùÓÚÖ¸¶¨xyÆ«ÒÆµÄÐýת£¬×¢Òâ±ä»»Ó¦ÓöÔÏóÉèΪsublayerTransform£¬¼´±ä»»Í¼²ãµÄ×Óͼ²ã¡£
¼àÌý´¥Ãþ£¬±éÀú±ä»»Í¼²ãµÄ×Óͼ²ã£¬¶Ôÿ¸öͼ²ã½øÐеã»÷²âÊÔ£¬Ò»µ©³É¹¦ÏàÓ¦Á¢¼´Ìø³öÑ»·£¬²»ÓüÌÐø±éÀú¡£
ÉèÖñ任ͼ²ã£¬Ìí¼Óµ½ÊÓͼ½á¹¹Ê÷¡£
×¢£ºcurrentTransform.m##ÊÇɶ£¿Îʵúã¬ÊÇCATransform3DÊôÐÔ£¬´ú±í¾ØÕóÔªËØ¡£ÏëѧϰÈçÉÏ´úÂëÖеľØÕó±ä»»£¬Çë²Î¿¼RW½Ì³Ì×é³ÉÔ±Rich
TurtonµÄÈýά±ä»»ÓéÀÖ½Ìѧ£¬»¹ÓÐMark PospeselµÄ³õʶ¾ØÕóÏîÄ¿¡£
ÔÚ250 x 250µÄsomeViewÊÓͼÖÐÔËÐÐÉÏÊö´úÂë½á¹ûÈçÏ£º

ÔÙÊÔÊÔµã»÷Á¢·½ÌåµÄÈÎÒâλÖ㬿ØÖÆÌ¨»áÊä³ö¡°Transform layer tapped!¡±ÐÅÏ¢¡£
ͼ²ãÑÝʾӦÓÃÖпÉÒÔµ÷Õû͸Ã÷¶È£¬´ËÍâBill Dudney¹ì¼£Çò¹¤¾ß, SwiftÒÆÖ²°æ¿ÉÒÔ»ùÓÚ¼òµ¥µÄÓû§ÊÖÊÆÓ¦ÓÃÈýά±ä»»¡£

ʾÀý #10£ºCAEmitterLayer
CAEmitterLayeräÖȾµÄ¶¯»Á£×ÓÊÇCAEmitterCellʵÀý¡£CAEmitterLayerºÍCAEmitterCell¶¼°üº¬¿Éµ÷ÕûäÖȾƵÂÊ¡¢´óС¡¢ÐÎ×´¡¢ÑÕÉ«¡¢ËÙÂÊÒÔ¼°ÉúÃüÖÜÆÚµÄÊôÐÔ¡£Ê¾ÀýÈçÏ£º
import UIKit class ViewController: UIViewController { // 1 let emitterLayer = CAEmitterLayer() let emitterCell = CAEmitterCell() // 2 func setUpEmitterLayer() { emitterLayer.frame = view.bounds emitterLayer.seed = UInt32(NSDate().timeIntervalSince1970) emitterLayer.renderMode = kCAEmitterLayerAdditive emitterLayer.drawsAsynchronously = true setEmitterPosition() } // 3 func setUpEmitterCell() { emitterCell.contents = UIImage(named: "smallStar")?.CGImage emitterCell.velocity = 50.0 emitterCell.velocityRange = 500.0 emitterCell.color = UIColor.blackColor().CGColor emitterCell.redRange = 1.0 emitterCell.greenRange = 1.0 emitterCell.blueRange = 1.0 emitterCell.alphaRange = 0.0 emitterCell.redSpeed = 0.0 emitterCell.greenSpeed = 0.0 emitterCell.blueSpeed = 0.0 emitterCell.alphaSpeed = -0.5 let zeroDegreesInRadians = degreesToRadians(0.0) emitterCell.spin = degreesToRadians(130.0) emitterCell.spinRange = zeroDegreesInRadians emitterCell.emissionRange = degreesToRadians(360.0) emitterCell.lifetime = 1.0 emitterCell.birthRate = 250.0 emitterCell.xAcceleration = -800.0 emitterCell.yAcceleration = 1000.0 } // 4 func setEmitterPosition() { emitterLayer.emitterPosition = CGPoint(x: CGRectGetMidX(view.bounds), y: CGRectGetMidY(view.bounds)) } func degreesToRadians(degrees: Double) -> CGFloat { return CGFloat(degrees * M_PI / 180.0) } override func viewDidLoad() { super.viewDidLoad() // 5 setUpEmitterLayer() setUpEmitterCell() emitterLayer.emitterCells = [emitterCell] view.layer.addSublayer(emitterLayer) } // 6 override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { setEmitterPosition() } } |
ÒÔÉÏ´úÂë½âÎö£º
1.´´½¨Á£×Ó·¢ÉäÆ÷ͼ²ãºÍÁ£×Ó°û£¨Creates an emitter layer and cell.£©¡£
2.°´ÕÕÏ·½²½ÖèÉèÖÃÁ£×Ó·¢ÉäÆ÷ͼ²ã£º
ÎªËæ»úÊýÉú³ÉÆ÷ÌṩÖÖ×Ó£¬Ëæ»úµ÷ÕûÁ£×Ó°ûµÄijЩÊôÐÔ£¬ÈçËÙ¶È¡£
ÔÚͼ²ã±³¾°É«ºÍ±ß½çÖ®Éϰ´renderModeÖ¸¶¨µÄ˳ÐòäÖȾÁ£×Ó°û¡£
×¢£ºäÖȾģʽĬÈÏΪÎÞÐò£¨unordered£©£¬ÆäËûģʽ°üÀ¨¾ÉÁ£×ÓÓÅÏÈ£¨oldest first£©£¬ÐÂÁ£×ÓÓÅÏÈ£¨oldest
last£©£¬°´zÖáλÖôӺóÖÁǰ£¨back to front£©»¹Óеþ¼ÓʽäÖȾ£¨additive£©¡£
ÓÉÓÚÁ£×Ó·¢ÉäÆ÷ÐèÒª·´¸´ÖØ»æ´óÁ¿Á£×Ó°û£¬ÉèdrawsAsynchronouslyΪtrue»áÌáÉýÐÔÄÜ¡£
È»ºó½èÖúµÚËÄÌõÖлáÌáµ½µÄ¸¨Öú·½·¨ÉèÖ÷¢ÉäÆ÷λÖã¬Õâ¸öÀý×ÓÓÐÖúÓÚÀí½â°ÑdrawsAsynchronouslyÉèΪtrueΪºÎÄܹ»ÌáÉýÐÔÄܺͶ¯»Á÷³©¶È¡£
3.Õâ¶Î´úÂëÉèÁ˲»ÉÙ¶«Î÷¡£
ÅäÖÃÁ£×Ó°û£¬ÉèÄÚÈÝΪͼƬ£¨Í¼Æ¬ÔÚͼ²ãÑÝʾÏîÄ¿ÖУ©¡£
Ö¸¶¨³õËÙ¼°Æä±ä»¯Á¿·¶Î§£¨velocityRange£©£¬·¢ÉäÆ÷ͼ²ãÀûÓÃÉÏÃæÌáµ½µÄËæ»úÊýÖÖ×Ó´´½¨Ëæ»úÊýÉú³ÉÆ÷£¬ÔÚ·¶Î§ÄÚ²úÉúËæ»úÖµ£¨³õÖµ+/-±ä»¯Á¿·¶Î§£©£¬ÆäËûÒÔ¡°Range¡±½áβµÄÏà¹ØÊôÐÔµÄËæ»ú»¯¹æÔòÀàËÆ¡£
ÉèÑÕɫΪºÚÉ«£¬Ê¹×Ô±äÉ«£¨variance£©ÓëĬÈϵİ×É«ÐγɶԱȣ¬°×É«ÐγɵÄÁ£×ÓÁÁ¶È¹ý¸ß¡£
ÀûÓÃËæ»ú»¯·¶Î§ÉèÖÃÑÕÉ«£¬Ö¸¶¨×Ô±äÉ«·¶Î§£¬ÑÕÉ«ËÙ¶ÈÖµ±íʾÁ£×Ó°ûÉúÃüÖÜÆÚÄÚÑÕÉ«±ä»¯¿ìÂý¡£
½ÓÏÂÀ´Õ⼸ÐдúÂëÖ¸¶¨Á£×Ó°û·Ö²¼·¶Î§£¬Ò»¸öȫԲ׶¡£ÉèÖÃÁ£×Ó°ûתËٺͷ¢É䷶Χ£¬·¢É䷶ΧemissionRangeÊôÐԵĻ¡¶ÈÖµ¾ö¶¨Á£×Ó°û·Ö²¼¿Õ¼ä¡£
ÉèÁ£×Ó°ûÉúÃüÖÜÆÚΪ1Ã룬ĬÈÏֵΪ0£¬±íʾÁ£×Ó°û²»»á³öÏÖ¡£birthRateÒ²ÀàËÆ£¬ÒÔÃëΪµ¥Î»£¬Ä¬ÈÏֵΪ0£¬ÎªÊ¹Á£×Ó°ûÏÔʾ³öÀ´£¬±ØÐëÉè³ÉÕýÊý¡£
×îºóÉèxy¼ÓËÙ¶È£¬ÕâЩֵ»áÓ°ÏìÒÑ·¢ÉäÁ£×ÓµÄÊӽǡ£
4.°Ñ½Ç¶Èת»»³É»¡¶ÈµÄ¸¨Öú·½·¨£¬»¹ÓÐÉèÖÃÁ£×Ó°ûλÖÃΪÊÓͼÖе㡣
5.ÉèÖ÷¢ÉäÆ÷ͼ²ãºÍÁ£×Ó°û£¬°ÑÁ£×Ó°ûÌí¼Óµ½Í¼²ã£¬È»ºó°Ñͼ²ãÌí¼Óµ½ÊÓͼ½á¹¹Ê÷¡£
6.iOS 8µÄз½·¨£¬´¦Àíµ±Ç°É豸ÐÎ̬¼¯£¨trait collection£©µÄ±ä»¯£¬±ÈÈçÉ豸Ðýת¡£²»ÊìϤÐÎ̬¼¯µÄ»°¿ÉÒÔ²ÎÔÄiOS
8½Ì³Ì¡£
×ÜËã˵ÍêÁË£¡ÐÅÏ¢Á¿ºÜ´ó£¬µ«ÏàП÷λ´ÏÃ÷µÄ¶ÁÕß¿ÉÒÔ¸ßЧÎüÊÕ¡£
ÉÏÊö´úÂëÔËÐÐЧ¹ûÈçÏ£º

ͼ²ãÑÝʾӦÓÃÖУ¬Äã¿ÉÒÔËæÒâµ÷½ÚºÜ¶àÊôÐÔ£º

|