[iOS] RippleEffectView:加载时实现与背景的涟漪效应(连锁反应)
mikeiii
8年前
<h2><strong>RippleEffectView</strong></h2> <p>Not only Uber-like animated loading screen background.</p> <p>RippleEffectView inspired by RayWenderlich.com article <a href="/misc/goto?guid=4959714027758030618" rel="nofollow,noindex">How To Create an Uber Splash Screen</a></p> <h2><strong>How it may looks like</strong></h2> <h3><strong>Basic customization (color randomization)</strong></h3> <pre> <code class="language-objectivec">rippleEffectView.tileImageRandomizationClosure = { rows, columns, row, column, image in let newImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) UIGraphicsBeginImageContextWithOptions(image.size, false, newImage.scale) UIColor.random.set() newImage.drawInRect(CGRectMake(0, 0, image.size.width, newImage.size.height)); if let titledImage = UIGraphicsGetImageFromCurrentImageContext() { UIGraphicsEndImageContext() return titledImage } UIGraphicsEndImageContext() return image }</code></pre> <pre> <code class="language-objectivec">rippleEffectView.magnitude = -0.6</code></pre> <p><img src="https://simg.open-open.com/show/b630db4fce1696981b16b1438c8af737.gif"></p> <pre> <code class="language-objectivec">rippleEffectView.magnitude = 0.2</code></pre> <p><img src="https://simg.open-open.com/show/1aef4f48d162e6bc12e334c47e421780.gif"></p> <h2><strong>Complex customization</strong></h2> <pre> <code class="language-objectivec">rippleEffectView.tileImageCustomizationClosure = { rows, columns, row, column, image in let newImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) UIGraphicsBeginImageContextWithOptions(image.size, false, newImage.scale) let xmiddle = (columns % 2 != 0) ? columns/2 : columns/2 + 1 let ymiddle = (rows % 2 != 0) ? rows/2 : rows/2 + 1 let xoffset = abs(xmiddle - column) let yoffset = abs(ymiddle - row) UIColor(hue: 206/360.0, saturation: 1, brightness: 0.95, alpha: 1).colorWithAlphaComponent(1.0 - CGFloat((xoffset + yoffset)) * 0.1).set() newImage.drawInRect(CGRectMake(0, 0, image.size.width, newImage.size.height)); if let titledImage = UIGraphicsGetImageFromCurrentImageContext() { UIGraphicsEndImageContext() return titledImage } UIGraphicsEndImageContext() return image }</code></pre> <pre> <code class="language-objectivec">rippleEffectView.rippleType = .Heartbeat rippleEffectView.magnitude = 0.2</code></pre> <p><img src="https://simg.open-open.com/show/cfb16b7de444946a13d2337f4f0e0a53.gif"></p> <h2><strong>Requirements</strong></h2> <ul> <li>Swift 2.3</li> <li>iOS 9.3+</li> <li>Xcode 7.3+</li> </ul> <h2><strong>Installation</strong></h2> <p>Copy RippleEffectView.swift to your project. Copy file if needed.</p> <h2><strong>Usage</strong></h2> <p>Add new RippleEffectView, assign tileImage and call startAnimating() .</p> <pre> <code class="language-objectivec">let rippleEffectView = RippleEffectView() rippleEffectView.image = UIImage(imageNamed: "someImage") rippleEffectView.animationDuration = 4 rippleEffectView.magnitude = 0.3 view.addSubview(rippleEffectView) rippleEffectView.startAnimating()</code></pre> <p>NB! startAnimating doesn't work if called in viewDidLoad and viewWillAppear. Working on fix. Place startAnimating() in viewDidAppear()</p> <h2><strong>Configurable properties</strong></h2> <p>NB! RippleEffectView initialize itself with parent view bounds automatically, so you do not need to set it manually. If you need to use it in limited view, then use auxiliary view, e.g.</p> <p>Animation uses transform , scale and opacity .</p> <pre> <code class="language-objectivec">TopView +- ContainerView +- RippleEffectView +- CALayer with animation</code></pre> <pre> <code class="language-objectivec">All regular UIView and layer properties.</code></pre> <ol> <li>tileImage UIImage that will displayed in every title. RippleEffectView uses size of image to calculate grid size. No default value.</li> <li>animationDuraton . Default 3.5</li> <li>magnitude force that will be applied to every circle to create ripple effect. Uber-like effect is about 0.1 - 0.2 . GIF example -0.8</li> <li>cellSize size of tile. Could be helpful if vector image used. Property is optional, if not set then tileImage size will be used.</li> <li>rippleType Type of ripple effect. .OneWave and .Heartbeat . Default .OneWave</li> </ol> <h2><strong>Read-only properties</strong></h2> <ol> <li>rows rows count</li> <li>columns columns count</li> </ol> <h2><strong>Methods</strong></h2> <p>stopAnimating Start ripple animation startAnimating Stop all animations</p> <h3>Manual control of the grid.</h3> <p>You need this if you change tileImageRandomizationClosure when animation did start. When you call renderGrid to recreate all items. If you want just remove all items (e.g. memory warning) then call removeGrid</p> <h2><strong>Callbacks</strong></h2> <h3><strong>Tile image customization.</strong></h3> <p>You may setup image for each grid view individually, or customize one that assigned in tileImage . (See example for full code)</p> <pre> <code class="language-objectivec">var tileImageRandomizationClosure: RandomizationClosure? = (Int, Int, UIImage)->(UIImage)</code></pre> <h3><strong>Animation Finished</strong></h3> <p>Main purpose of this component is to create animated screen background. You may stop animation and hide a screen as soon as data available, or wait for the animation end and the show the data.</p> <pre> <code class="language-objectivec">rippleEffectView.animationDidStop = { _ in // do something }</code></pre> <p> </p> <p>来自:https://github.com/alsedi/RippleEffectView</p> <p> </p>