Ne genellikle bu durumda ne şudur.
Sahnenize iki kısıtlama ekleyin. UIView2
'un bulunduğu yer, UIView1
'un altına hizalanır. İkincisi, nerede UIView1
merkezi hizalanmış (kısıtlamaları uygun şekilde eklemek için görünümler arasında ctrl + sürüklemek isteyeceksiniz). Bu kısıtlamalar başlangıçta birbirleriyle çakışacak ve bu iyi.
için görünüm denetleyicinize
IBOutlet
s ekleyin ve bu
IBOutlet
s için oluşturduğumuz iki kısıtlamayı atayın.
İlk koşulunuzdaki kısıtlama önceliğini 999 olarak ayarlayın (diğer bir deyişle, kısıtlama önceliği en altta 999 olmalıdır). Hedef kısıtlamadaki kısıtlama önceliğini 998 olarak ayarlayın (diğer bir deyişle hizalama merkezindeki sınırlama önceliği 998'dir). Artık bu kısıtlamaların artık çatışmayacağını göreceksiniz. Bunun nedeni, bir kısıtlamadaki önceliğin diğerini geçersiz kılmasıdır.
Bunun şimdi nereye gittiğini görebilirsiniz. Kısıtlamalar arasında UIView2
'u canlandırmak istediğinizde, öncelikleri değiştirin ve canlandırın!
Kodu:
@interface MyViewController()
@property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint0;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint1;
@end
- (void)someMethodWhereIWantToAnimate
{
NSInteger temp = self.constraint0.priority;
self.constraint0.priority = self.constraint1.priority;
self.constraint1.priority = temp;
[UIView animateWithDuration:0.3 animations:^{
// Simplest is to use the main ViewController's view
[self.view layoutIfNeeded];
}];
}
yatay kaydırmayı etkinleştirmek ve animasyon görünümü denetleyicisine Pan Hareket Tanıyıcı'yı eklemek başlatmak için kullanıyor belirleyin. Ctrl + UIView2
'dan Pan Gesture Recognizer'a sürükleyin ve bunu gestureRecognizer
olarak ayarlayın. Artık UIView2
’a sürüklediğinizde, pan olaylarını alabileceksiniz. görünüm denetleyiciye tava jest tanıyıcı
- (IBAction)onPan:(id)sender
{
}
Ctrl + sürükle ve gönderilen eylem olarak onPan:
ayarlayın:
tavayı işlemek için IBAction ekleyin. Aslında, pan jest tanılayıcısının kendisinin aslında
sender
. Bu nedenle, bir tava ele almak ve kullanıcının parmağının altında UIView2
takip etmek için bu yöntemi doldurabileceğiz ve sonra bıraktıklarında animasyonu başlatacağız.O
State: (1) Translation in view: (0.000000, -2.500000)
State: (2) Translation in view: (0.500000, -7.500000)
State: (2) Translation in view: (0.500000, -7.500000)
State: (2) Translation in view: (1.500000, -12.000000)
State: (2) Translation in view: (2.500000, -16.500000)
State: (2) Translation in view: (2.500000, -19.500000)
State: (2) Translation in view: (2.500000, -24.500000)
State: (2) Translation in view: (2.500000, -25.000000)
State: (2) Translation in view: (2.500000, -25.500000)
State: (2) Translation in view: (2.500000, -27.000000)
State: (2) Translation in view: (2.500000, -29.500000)
State: (2) Translation in view: (2.500000, -31.000000)
State: (2) Translation in view: (2.500000, -31.500000)
State: (3) Translation in view: (2.500000, -31.500000)
Uyarı: Eğer böyle çıktı göreceksiniz,
- (IBAction)onPan:(id)sender
{
UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender;
CGPoint translation = [recognizer translationInView:self.view];
NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, translation.x, translation.y);
}
bu kodla çalıştırırsanız, ve UIView2
üzerinde parmağınızı sürükleyerek:
kodunu doldurarak başlayalım değerler sürekli artmaktadır. Artımlı miktarı isteyeceğiz. Durumdaki durumu dikkat edin. Durum (1) sürükleme başlangıcıdır. Durum (2) sürükle değiştirilir. Devlet (3) sürükle sona erdi. Bu bilgiyi kullanarak deltayı hesaplayabiliriz.
- (IBAction)onPan:(id)sender
{
UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender;
CGPoint delta;
switch(recognizer.state) {
case UIGestureRecognizerStateBegan:
// On state begin: delta is the translation. Store it in our member for later user.
self.lastTranslation = delta = [recognizer translationInView:self.view];
break;
case UIGestureRecognizerStateChanged:
// On state changed: calculate the difference between the translation and our
// previous translation.
delta = CGPointApplyAffineTransform([recognizer translationInView:self.view], CGAffineTransformMakeTranslation(-self.lastTranslation.x, -self.lastTranslation.y));
self.lastTranslation = [recognizer translationInView:self.view];
break;
case UIGestureRecognizerStateEnded:
// On state ended: Let's just do the constraint animation.
[self someMethodWhereIWantToAnimate];
break;
default:
break;
}
delta.x = 0; // Forces only vertical drag on the UIView2.
self.uiView2.center = CGPointApplyAffineTransform(self.uiView2.center, CGAffineTransformMakeTranslation(delta.x, delta.y)); // Move our uiView2 based on the delta.
NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, delta.x, delta.y);
}
Bunu yaparken: en bizim tava yönteminin son formu doldurun izin
@property (nonatomic) CGPoint lastTranslation;
@property (nonatomic, weak) IBOutlet UIView* uiView2;
Son olarak:
görünümünüzü denetleyicisine bir CGPoint
Özellik ekle ve yanı bir IBOutlet olarak UIView2 eklemek Seni yolda iyi al. UIView animasyonunu, pan hareketinin velocityInView:
yöntemine dayanan kısıtlamalarla düzeltmek isteyebilirsiniz, ancak bir egzersiz olarak ayrılacağım.
Kısıtlama1'in dikey merkez kısıtlaması olduğunu mu varsayıyorum? ... belki okumayı özledim ama kısıtlama ne anlama geliyor? – Pangu
Evet, kısıtlama0 altta hizalanacak kısıtlama olurdu. Kısıtlama1 merkezi dikey kısıtlama olur. @Pangu –
UIView2'nin tamamen UIView1'in içindeki UIView1'in penceresinin dışında olduğu gerçeğine ne dersiniz? ... kendi içinde de kendi kısıtlama çatışmasını yaratmaz mı? – Pangu