2011-11-29 20 views
22

Tôi có một đối tượng UIView mà quay sử dụng CALayer 's transform:Antialiasing cạnh của UIView sau khi chuyển đổi sử dụng CALayer của transform

// Create uiview object. 
UIImageView *block = [[UIImageView alloc] initWithFrame....] 

// Apply rotation. 
CATransform3D basicTrans = CATransform3DIdentity; 
basicTrans.m34 = 1.0/-distance; 
blockImage.layer.transform = CATransform3DRotate(basicTrans, rangle, 1.0f, 0.0f, 0.0f); 

Sau khi quay các cạnh của đối tượng không phải là khử răng cưa. Tôi cần phải chống lại họ. Xin hãy giúp tôi. Nó được hoàn thiện bằng cách nào?

Trả lời

41

Một cách để thực hiện việc này là đặt hình ảnh bên trong một chế độ xem khác lớn hơn 5 pixel. Quan điểm lớn hơn nên có đường viền rasterized minh bạch mà sẽ mịn các cạnh của UIImageView:

view.layer.borderWidth = 3; 
view.layer.borderColor = [UIColor clearColor].CGColor; 
view.layer.shouldRasterize = YES; 
view.layer.rasterizationScale = [[UIScreen mainScreen] scale]; 

Sau đó, đặt UIImageView của bạn bên trong nhìn mẹ này và tập trung nó (Với 2,5 pixel xung quanh mỗi cạnh).

Cuối cùng, xoay chế độ xem gốc thay vì chế độ xem hình ảnh.

Tính năng này hoạt động rất tốt - bạn cũng có thể đóng gói toàn bộ nội dung trong lớp tạo phân cấp.

+9

Bạn có thể muốn thêm 'view.layer.rasterizationScale = [[UIScreen mainScreen] scale];' để tránh bị mờ trên màn hình Retina. –

+0

Nhận xét này phải là một phần của câu trả lời. Đặt thuộc tính 'shouldRasterize' là không đủ! –

+0

Bạn nói đúng. Làm xong. – tarmes

30

Chỉ cần thêm cặp khóa-giá trị này vào Info.plist: UIViewEdgeAntialiasing được đặt thành YES.

+1

Đây là kẻ giết người! – orkenstein

+0

tuyệt vời! Bất kỳ ý tưởng nào về hiệu suất đạt được? – horseshoe7

+0

Nó đi kèm với hình phạt hiệu suất, tránh nó nếu bạn có thể. –

3

Tôi gặp sự cố tương tự khi xoay quanh trục z. Thiết lập shouldRasterize = YES ngăn chặn các cạnh bị lởm chởm tuy nhiên nó có chi phí hiệu năng. Trong trường hợp của tôi, tôi đã sử dụng lại các khung nhìn (và các lớp của nó) và giữ cho shouldRasterize = YES làm chậm mọi thứ.

Giải pháp là tắt tính năng rasterization ngay sau khi tôi không cần nữa. Tuy nhiên, kể từ khi hình ảnh động chạy trên một chủ đề khác, không có cách nào để biết khi nào hoạt hình hoàn tất ... cho đến khi tôi tìm ra một phương pháp CATransaction cực kỳ hữu ích. Đây là một mã thực tế mà tôi đã sử dụng và nó nên minh họa cho việc sử dụng nó:

// Create a key frame animation 
CAKeyframeAnimation *wiggle = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 
NSInteger frequency = 5; // Higher value for faster vibration 
NSInteger amplitude = 25; // Higher value for lower amplitude 
// Create the values it will pass through  
NSMutableArray *valuesArray = [[NSMutableArray alloc] init]; 
NSInteger direction = 1; 

[valuesArray addObject:@0.0]; 

for (NSInteger i = frequency; i > 0; i--, direction *= -1) { 
    [valuesArray addObject:@((direction * M_PI_4 * (CGFloat)i/(CGFloat)amplitude))]; 
} 

[valuesArray addObject:@0.0]; 
[wiggle setValues:valuesArray]; 

// Set the duration 
[wiggle setAdditive:YES]; 
[wiggle setValueFunction:[CAValueFunction functionWithName:kCAValueFunctionRotateZ]]; 
[wiggle setDuration:0.6]; 

// Turn on rasterization to prevent jagged edges (anti-aliasing issues) 
viewToRotate.layer.shouldRasterize = YES; 

// ************ Important step ************** 
// Very usefull method. Block returns after ALL animations have completed. 
[CATransaction setCompletionBlock:^{ 
    viewToRotate.layer.shouldRasterize = NO; 
}]; 
// Animate the layer 
[viewToRotate.layer addAnimation:wiggle forKey:@"wiggleAnimation"]; 

làm việc như một sự quyến rũ đối với tôi.

Tôi chưa thử sử dụng điều này với hoạt ảnh ngầm định (tức là hoạt ảnh xảy ra do thay đổi giá trị trong thuộc tính có thể hoạt hình cho lớp không được xem), tuy nhiên tôi mong đợi nó hoạt động miễn là phương thức CATransaction được gọi trước thay đổi thuộc tính, cũng giống như một sự đảm bảo rằng block được gán cho CATransaction trước khi một hình động bắt đầu.

20

kiểm tra allowsEdgeAntialiasing thuộc tính của CALayer.

block.layer.allowsEdgeAntialiasing = YES; // iOS7 and above. 
+1

giống như trên (Info.plist) nhưng kiểm soát chi tiết hơn! Xuất sắc! – horseshoe7

+1

Câu trả lời được chấp nhận không hoạt động giống như câu trả lời này, nhưng câu trả lời này hoạt động tốt hơn. Cả hai chi tiêu cùng một RAM, nhưng giải pháp này cung cấp FPS cao hơn cho người dùng. –

+0

Tài liệu cho thuộc tính này cho biết giá trị là KHÔNG nếu giá trị Info.plist vắng mặt.Rõ ràng, bạn không thể chỉ đơn giản là thiết lập tài sản này nhưng phải sử dụng nó kết hợp với plist. Tôi đã không kiểm tra những gì sẽ xảy ra nếu tài sản không được thiết lập, nhưng đánh giá từ câu trả lời của AddisDev, nó mặc định là có trong trường hợp đó. Vì vậy, nếu có một hit hiệu suất và bạn không cần antialiasing, có vẻ như điều cần làm là đặt giá trị này thành NO. –

Các vấn đề liên quan