https://www.bignerdranch.com/blog/uidynamics-in

Transkrypt

https://www.bignerdranch.com/blog/uidynamics-in
https://www.bignerdranch.com/blog/uidynamics-in-swift/
http://www.raywenderlich.com/76147/uikit-dynamics-tutorial-swift
http://www.sitepoint.com/using-uikit-dynamics-swift-animate-apps/
Zrób kwadrat
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
zrobBox(CGRectMake(100,100,30,30), kolor: UIColor.redColor())
}
func zrobBox(ramka: CGRect, kolor: UIColor) {
let b = UIView(frame: location)
b.backgroundColor = kolor
view.insertSubview(b, atIndex: 0)
}
}
Dodaj składniki klasy: animator i grawitację
var animator = UIDynamicAnimator()
let gravity = UIGravityBehavior()
override func viewDidLoad() {
super.viewDidLoad()
zrobAnimator()
zrobBox(CGRectMake(100,100,30,30))
}
// (0,0) jest w lewym górnym wierzchołku ekranu
func zrobBox(ramka: CGRect, kolor: UIColor) {
let b = UIView(frame: location)
b.backgroundColor = kolor
view.insertSubview(b, atIndex: 0)
gravity.addItem(b)
}
func zrobAnimator() {
animator = UIDynamicAnimator(referenceView: self.view)
gravity.gravityDirection = CGVectorMake(0, 0.4)
animator.addBehavior(gravity)
}
}
Dodaj collider, na początek obsługa granic widoku
let collider = UICollisionBehavior()
// składnik klasy
w funkcji zróbBox: collider.addItem(b)
w funkcji zrobAnimator:
collider.translatesReferenceBoundsIntoBoundary = true
animator.addBehavior(collider)
Dodaj własną granicę do collidera, zrób barierę
override func viewDidLoad() {
super.viewDidLoad()
zrobAnimator()
bariera()
zrobBox(CGRectMake(130,100,30,30)) // wypróbuj różne wartości x boxa
}
func bariera() {
let bar = UIView(frame: CGRectMake(0,330,140,5));
bar.backgroundColor = UIColor.blueColor()
self.view.addSubview(bar)
let lewy = CGPointMake(0, 330)
let prawy = CGPointMake(140, 330)
collider.addBoundaryWithIdentifier("gornaKrawedzBariery", fromPoint: lewy, toPoint: prawy)
}
Dodaj UIDynamicItemBehaviour - można przypisać różne cechy do dynamicznych elementów:
friction - tarcie - liczba rzeczywista z przedziału od 0 do 1, która określa, jak bardzo odporny na
ruch produkt będzie, gdy przesuwa się na inne przedmioty lub inne przedmioty przesuń na jego
krawędziach.
elasticity - liczba rzeczywista z przedziału od 0 do 1, która określa sprężystość kolizji elementu.
density - wykorzystywana przez animatora do obliczania masy elementu, domyślnie 1, zakres 0-1
allowsRotation - wartość logiczna, czy produkt może być obracany przez animatora.
resistance - opory ruchu, od 0 do CGFLOAT_MAX
angularResistance - opory w ruchu obrotowym
składnik klasy:
let dynamic = UIDynamicItemBehavior()
do funkcji zrobAnimator:
animator.addBehavior(dynamic)
dynamic.friction = 0.1
dynamic.elasticity = 0.9
// wypróbuj inne wartości, np 1.2
do funkcji zrobBox:
dynamic.addItem(b)
Dodaj detekcję parametrów kolizji: licznik kolizji i identyfikator obiektu kolidującego
Klasa VievController musi implementować protokół: UICollisionBehaviorDelegate
i zdefiniować delegata do detekcji kolizji (w funkcji zrobAnimator):
collider.collisionDelegate = self
wówczas można w klasie ViewController zdefiniować licznik kolizji
var liczkolizje: Int = 0
i zaimplementować funkcję tego protokołu:
func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, atPoint p: CGPoint) {
liczkolizje++
print("licznik kolizji = \(liczkolizje) obiekt = \(identifier)”)
let v: UIView = item as! UIView
let kolor = v.backgroundColor
v.backgroundColor = UIColor.yellowColor()
UIView.animateWithDuration(1.0, animations: {
v.backgroundColor = kolor
})
// zapamiętaj jaki był kolor boxa
// zmiana koloru przy kolizji
}
Wiele boxów
Nowy składnik klasy ViewController, tablica box-ów. Nowo tworzony box nie może kolidować z
żadnym wcześniej utworzonym. W tym celu zapamiętaj wszystkie tworzone boxy w tablicy:
var B = [UIView]()
Dodaj we funkcji zrobBox: B.append(b)
Nowe funkcje
func koliduje(ramka: CGRect) -> Bool {
for b in B {
let r = b.frame;
if(CGRectIntersectsRect(ramka, r)) { return true }
}
return false
}
func losowyBox() -> CGRect {
var box = CGRectZero
repeat {
let x = CGFloat(arc4random()) % 320 // losuj z szerokości widoku
let y = CGFloat(arc4random()) % 400 // losuj z wysokości widoku
box = CGRectMake(x, y, 30, 30);
} while(koliduje(box))
return box
}
func losowyKolor() -> UIColor {
let red = CGFloat(CGFloat(arc4random()%255)/255);
let green = CGFloat(CGFloat(arc4random()%255)/255);
let blue = CGFloat(CGFloat(arc4random()%255)/255);
return UIColor(red: red, green: green, blue: blue, alpha: 0.85);
}
Zmiana we funkcji viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
zrobAnimator()
bariera()
// zrobBox(CGRectMake(130,100,30,30),kolor: UIColor.redColor())
for _ in 0..<10 {
let box = losowyBox() // taka ramka która nie koliduje z innym boxem
let kolor = losowyKolor()
zrobBox(box, kolor: kolor);
}
}
Jak przerobić kwadraty na kółka
we funkcji zróbBox zaokrąglij narożniki tworzonego boxa
func zrobBox(ramka: CGRect, kolor: UIColor) {
let b = UIView(frame: ramka)
b.backgroundColor = kolor
b.layer.cornerRadius = 15
// połowa boku kwadratu
view.insertSubview(b, atIndex: 0)
gravity.addItem(b)
collider.addItem(b)
dynamic.addItem(b)
B.append(b) // tablica boxów, aby wybrać następny box nie kolidujący z dotychczasowymi
}
Zmień typ granicy stosowanej do detekcji kolizji. Domyślnie jest prostokąt, zmień na elipsę
class Kolko: UIView {
override var collisionBoundsType: UIDynamicItemCollisionBoundsType {
return .Ellipse
}
}
We funkcji zrobBox() zmień klasę tworzonego obiektu, zamiast UIView zrób Kolko
// let b = UIView(frame: ramka)
let b = Kolko(frame: ramka)
W odpowiedzi na touch-dragging zmień wektor grawitacji
W Main.storyboard, przeciągnij na widok z Object Library kontrolkę PanGestureRecognizer,
z jej ikony zrób akcję:
@IBAction func ciagnij(sender: UIPanGestureRecognizer) {
// let translation = sender.translationInView(view)
let v = sender.velocityInView(view)
let dx = 0.01*v.x
let dy = 0.01*v.y
print(" dx = \(dx) dy = \(dy)")
gravity.gravityDirection = CGVectorMake(dx, dy)
}

Podobne dokumenty