Tôi đang cố gắng tạo điều khiển quay số, về cơ bản là 6 chữ số quay xung quanh để tạo hiệu ứng của đồng hồ đo quay số (tương tự như công suất/nước của bạn) mét, hoặc có lẽ một máy poker, trên thực tế rất giống với điều khiển UIPickerView hiện có, nhưng với một cái nhìn hoàn toàn khác và cảm nhận).Các khó khăn về hoạt ảnh lõi với điều khiển quay số (rất chi tiết)
Cho đến nay, tôi gần như đã làm việc, nhưng Im ở một giai đoạn mà hoạt hình cốt lõi là cho tôi đau buồn.
Đoạn mã rất phức tạp của nó sẽ rất khó để có được ảnh chụp nhanh về những gì đang diễn ra, vì vậy tôi nghĩ mã giả sẽ đủ.
Thứ nhất, về thiết lập chế độ xem, tôi có 6 riêng biệt UIView
s (được gọi là NumberView1, NumberView2, v.v ...), mỗi cái cho mỗi số trong điều khiển.
Bên trong mỗi NumberViewX tôi đã khác UIView
, đó là một cái nhìn container, gọi ContainerView1, 2, vv ...
Sau đó tôi có 10 UIImageView
s xếp chồng lên nhau tại các độ lệch Y khác nhau. Những hình ảnh này là tất cả 30x30 mà làm cho nó tốt đẹp. 9 là đầu tiên, sau đó 8 tại y-bù 30, sau đó 7 tại y-bù đắp 60, vv ... tất cả các con đường xuống 0 tại y-offset 270.
LƯU Ý QUAN TRỌNG: Các con số của tôi chỉ bao giờ cuộn lên trên
Các số đại diện cho số điểm 5 thập phân (nghĩa là 2.34677) sẽ cuộn lên (ví dụ: 2.61722).
Tôi cũng có một số từ điển mà giữ giá trị số hiện tại cho mỗi số và hiệu số cho mỗi số:
NSArray *offsets = [[NSArray alloc] initWithObjects:
[NSNumber numberWithInt:0], //9
[NSNumber numberWithInt:-30], //8
[NSNumber numberWithInt:-60], //7
[NSNumber numberWithInt:-90], //6
[NSNumber numberWithInt:-120], //5
[NSNumber numberWithInt:-150], //4
[NSNumber numberWithInt:-180], //3
[NSNumber numberWithInt:-210], //2
[NSNumber numberWithInt:-240], //1
[NSNumber numberWithInt:-270], //0
nil];
NSArray *keys = [[NSArray alloc] initWithObjects:
[NSNumber numberWithInt:9],
[NSNumber numberWithInt:8],
[NSNumber numberWithInt:7],
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:5],
[NSNumber numberWithInt:4],
[NSNumber numberWithInt:3],
[NSNumber numberWithInt:2],
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:0], nil];
offsetDict = [[NSDictionary alloc] initWithObjects:offsets forKeys:keys];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:2] forKey: [NSValue valueWithNonretainedObject: self.containerViewDollarSlot1]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:8] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace1]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:3] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace2]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:3] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace3]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:8] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace4]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:5] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace5]];
Bây giờ cho logic, tôi bắt đầu thiết lập các thuộc lớp của ContainerView được offsets nhất định Y sẽ chuyển các số hiện tại vào các vị trí chính xác của chúng, như vậy:
self.containerViewDollarSlot1.layer.transform = CATransform3DTranslate(self.containerViewDollarSlot1.layer.transform, 0, -210, 0);
self.containerViewDecimalPlace1.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace1.layer.transform, 0, -30, 0);
self.containerViewDecimalPlace2.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace2.layer.transform, 0, -180, 0);
self.containerViewDecimalPlace3.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace3.layer.transform, 0, -180, 0);
self.containerViewDecimalPlace4.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace4.layer.transform, 0, -30, 0);
self.containerViewDecimalPlace5.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace5.layer.transform, 0, -120, 0);
sẽ hiển thị số, 2.83385, là số tùy ý để kiểm tra.
Sau đó, tôi nhập vào một giá trị trong một textbox và nhấn nút đi tour diễn khởi động logic hình ảnh động, đó là nơi mà tôi nhận được những khó khăn trong Core Animation (như tựa đề)
tôi gọi:
[self animateDecimalPlace: 0
withAnimation: self.dollarSlot1Animation
andContainerView: self.containerViewDollarSlot1];
[self animateDecimalPlace: 1
withAnimation: self.decimalPlace1Animation
andContainerView: self.containerViewDecimalPlace1];
//etc... for all 6 numbers
nơi dollarSlot1Animation là Ivar CABasicAnimation
phương pháp này được định nghĩa dưới đây:
- (void) animateDecimalPlace: (int) decimalIndex withAnimation: (CABasicAnimation*)animation andContainerView: (UIView*) containerView{
NSRange decimalRange = {decimalIndex == 0 ? 0 : 2,
decimalIndex == 0 ? 1 : decimalIndex};
double diff = 0;
if (decimalIndex == 0)
{
int decimalPartTarget = [[[NSString stringWithFormat:@"%f", targetNumber] substringWithRange: decimalRange] intValue];
int decimalPartCurrent = [[[NSString stringWithFormat:@"%f", currentValue] substringWithRange: decimalRange] intValue];
diff = decimalPartTarget - decimalPartCurrent;
}
else {
double fullDiff = targetNumber - currentValue;
diff = [[[NSString stringWithFormat:@"%f", fullDiff] substringWithRange: decimalRange] doubleValue];
}
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeRemoved;
animation.duration = 5.0;
NSNumber *n = [currentValuesForDecimalPlace objectForKey:[NSValue valueWithNonretainedObject: containerView]];
NSNumber *offset = (NSNumber*)[offsetDict objectForKey: n];
int rotations = [self setupNumberForAnimation: diff decimalIndex: decimalIndex forContainer: containerView];
int finalOffset = (rotations*30)+([offset intValue]);
CATransform3D translation = CATransform3DMakeTranslation(0, finalOffset, 0);
animation.fromValue = [NSValue valueWithCATransform3D:containerView.layer.transform];
animation.toValue = [NSValue valueWithCATransform3D:translation];
animation.delegate = self;
[containerView.layer addAnimation: animation forKey: [NSString stringWithFormat:@"%i", decimalIndex] ];
}
Như bạn có thể thấy (hoặc có lẽ không :)) Tôi đang xử lý từng số độc lập về cơ bản, và yêu cầu nó dịch sang vị trí Y mới, nhưng bạn có thể nhận thấy một phương thức có tên là setupNumberForAnimation
. tự động thêm nhiều hơn UIImageView
s vào vùng chứa UIView phía trên 10 hình ảnh ban đầu.
Ví dụ: có 10 ô để bắt đầu, nếu tôi muốn cuộn số quay 21 điểm (ví dụ từ 3 đến 24), tôi sẽ cần thêm 15 số mới trên 9, sau đó tạo hiệu ứng động bản dịch của chế độ xem vùng chứa lên đến ô hình ảnh hàng đầu nhất.
Sau khi cuộn xong, tôi xóa tự động thêm UIImageView
s và định vị lại giá trị y của chế độ xem của vùng chứa trở lại giá trị trong khoảng từ 0 đến -270 (về cơ bản kết thúc trên cùng một số, nhưng xóa tất cả - xem hình ảnh cần thiết).
Điều này mang lại hiệu ứng động mượt mà sau đó. Và nó hoạt động. Hãy tin tôi :)
Vấn đề của tôi gấp hai lần, trước tiên khi hoạt ảnh ngừng hoạt ảnh Core Animation, hãy chuyển đổi hoạt ảnh thành lớp vì tôi đã đặt animation.fillMode = kCAFillModeRemoved;
Tôi không thể hiểu được cách sau khi hoàn tất hoạt ảnh. y bù đắp, tôi biết nó âm thanh lẻ, nhưng nếu tôi có thuộc tính fillMode thiết lập để kCAFillModeForwards, không có gì tôi đã cố gắng dường như có tác dụng trên lớp. Thứ hai, khi hoạt ảnh dừng lại và thay đổi được hoàn nguyên, có một nhấp nháy nhỏ giữa khi hoạt ảnh trở lại bản dịch và khi tôi đặt lại bản dịch, tôi không thể tìm ra cách để giải quyết vấn đề này.
Tôi biết có một đống chi tiết và tính đặc hiệu ở đây, nhưng bất kỳ trợ giúp hoặc ý tưởng nào về cách thực hiện điều này sẽ được đánh giá rất nhiều.
Thanks a lot
Nó đánh bại mơ hồ (như nhận xét này). – BoltClock
Một luận án để đánh giá bởi một giáo sư;) –
Cảm ơn vì "giúp đỡ" ... Tôi biết một bài viết chi tiết, nhưng Im mở ý tưởng khác là tốt, Im hạnh phúc để phế liệu thực hiện của tôi hoàn toàn – Mark