2010-01-02 45 views
11

Tôi có một dòng UILabel nhiều dòng mà tôi muốn bật tính năng phóng to.Zoom UILabel & Hiển thị lại phông chữ ở kích thước chính xác

tôi nhúng nó với một UIScrollView và thiết lập phút zoom tới .25 và zoom tối đa đến 4. này hoạt động tốt, tuy nhiên UILabel tôi 's phông chữ trông khá thô ở bất kỳ cấp độ zoom khác hơn 1.

tôi có thể xử lý phương thức này:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 

để kích thước lại phông chữ UILabel của tôi thành thứ gì đó lớn hơn, nhưng chế độ xem vẫn được phóng to, vì vậy nó luôn trông khủng khiếp.

Có cách nào để làm cho văn bản của nhãn hiển thị lại một lần tôi đã phóng to xong không?

Điều quan trọng là vị trí cuộn hiện tại của người dùng trong văn bản không bị mất.

(Để có cảm nhận về những gì tôi đang làm, hãy chú ý đến cách thức di chuyển trong Safari khi bạn phóng to văn bản được chia tỷ lệ/chống răng cưa trong một giây rồi chia nhỏ để hiển thị tốt ở quy mô thu phóng hiện tại của bạn)

Trả lời

16

Tỷ lệ được tích hợp sẵn của UIScrollView chỉ áp dụng biến đổi cho chế độ xem nội dung của bạn, dẫn đến độ mờ ở bất kỳ giá trị nào trên hệ số tỷ lệ là 1,0. Để thực sự hiển thị sắc nét, bạn sẽ cần phải tự xử lý tỷ lệ. Tôi mô tả một đoạn của quá trình trong this answer.

Bạn sẽ cần theo dõi hệ số tỷ lệ của chế độ xem nội dung theo cách thủ công, sau đó trong -scrollViewDidEndZooming: withView: atScale: phương thức ủy nhiệm bạn sẽ áp dụng thang đo đó. Đối với UILabel của bạn, điều đó có nghĩa là thay đổi kích thước phông chữ để phản ánh quy mô mới.

Để duy trì vị trí cuộn chính xác, bạn sẽ cần phải lấy contentOffset của UIScrollView trong phương thức ủy nhiệm ở trên và tính toán vị trí tương ứng với UILabel mới được chia tỷ lệ. Sau đó bạn thiết lập contentSize của khung nhìn cuộn để phù hợp với kích thước mới của UILabel và sử dụng -setContentOffset: animated: để thiết lập offset nội dung mới được tính toán (với bộ động là NO).

Đó là một chút khó khăn để có được quyền toán, nhưng tôi làm điều này khi mở rộng văn bản trong một trong các ứng dụng của tôi, có thể được nhìn thấy trong video demonstration of that application (vào khoảng 1/3 nhãn).

+0

Cảm ơn câu trả lời chi tiết. điều này có nghĩa là tôi cần phải từ bỏ tính năng phóng to tích hợp của chế độ xem cuộn? Hoặc khi tôi phóng to xong, tôi chỉ render lại bề mặt ở hệ số tỷ lệ mới? Điều này làm gì với cài đặt thu phóng tối thiểu/tối đa của bạn? –

+0

Bạn sử dụng tính năng phóng to được tích hợp trong khi cử chỉ chụm đang diễn ra, sau đó hiển thị lại khi cử chỉ kết thúc. Đây là cách duy nhất để có được hiệu suất thu nhỏ chụm. UIScrollView theo dõi quy mô thu phóng tổng thể (đó là lý do tại sao bạn cần ghi đè trình biến đổi trên chế độ xem nội dung để chống lại điều này), do đó, nó sẽ vẫn quan sát cài đặt thu phóng tối thiểu/tối đa. –

+0

Bắt đầu có ý nghĩa hơn. Vì vậy, nếu tôi phóng to 150%, tôi có thể thay đổi kích thước phông chữ của nhãn thành 1.5 * currentFontSize, tính lại vị trí cuộn chính xác của chúng và hiển thị lại nhãn của tôi. Sau đó, tôi thiết lập lại zoom đến 1 và tính lại min/max của tôi? Tôi có quyền này không? –

0

Có một cách đơn giản hơn để làm điều này ..

Thay layerClass của UILabel với một CATiledLayer và thiết lập các mức độ chi tiết thích hợp.

+ (Class)layerClass 
{ 
    CATiledLayer *layerForView = (CATiledLayer *)self.layer; 
    layerForView.levelsOfDetailBias = 2; 
    layerForView.levelsOfDetail = 2; 
    return [CATiledLayer class]; 
} 

việc thực hiện

+0

Tai nạn cho tôi ... – jjxtra

+0

Bạn đã nhập QuarzCore chưa? – JEzu

+3

self.layer sẽ không hoạt động trong một phương thức lớp. –

2

cách chính xác để thay thế một CALayer với một CATiledLayer là như sau:

+ (Class)layerClass { 
    return [CATiledLayer class]; 
} 

ngoài, bạn đã thiết lập chi tiết sai lệch của bạn và bất cứ điều gì bạn cần.

7

Cảm ơn valvoline & Gây nhầm lẫn cho câu trả lời của bạn. Giải pháp của tôi là sự pha trộn giữa bạn.

Subclass UILabel như thế này:

UILabelZoomable.h

+ (Class) layerClass; 

UILabelZoomable.m

+ (Class) layerClass 
{  
    return [CATiledLayer class]; 
} 

Bây giờ, khi bạn sử dụng ưa thích của bạn UILabelZoomable mới trong ứng dụng của bạn, hãy nhớ để làm điều này :

YourViewController.m

CATiledLayer *tiledLayer = (CATiledLayer*)textoLabel.layer; 
tiledLayer.levelsOfDetail = 10; 
tiledLayer.levelsOfDetailBias = 10; 

Hãy nhớ thêm khung công tác QuartzCore!

#import <QuartzCore/QuartzCore.h> 

Thưởng thức sắc nét và một văn bản trả lại đẹp:

[UIView animateWithDuration:1 animations:^ 
    { 
     yourLabel.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(200, 200), CGAffineTransformMakeRotation(1)); 
    }]; 
+1

Tai nạn cho tôi ... – jjxtra

+0

Điều gì xảy ra với dòng cuối cùng? CGAffineTransformMakeRotation (1) xoay nhãn xung quanh 1 radian. –

2

tôi kiểm tra mã JEzu trong iOS 5.1 và 6 beta, nó đang làm việc cho một nhãn văn bản const, nhưng gây nhãn bình thường khác yêu cầu cập nhật văn bản nội dung không thành công, tức là văn bản không bị thay đổi ...

Tôi phân lớp UILabel thành ZoomableLabel bằng câu trả lời của JEzu và áp dụng lớp làm lớp tùy chỉnh của nhãn và nó hoạt động tốt.

7

iOS 4+

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { 
    scrollView.contentScaleFactor = scale; 
    for (UIView *subview in scrollView.subviews) { 
     subview.contentScaleFactor = scale; 
    } 
} 

Nếu đây trở nên quá chuyên sâu và hiệu suất là chậm, chỉ cần cố gắng thiết lập các contentScaleFactor chỉ nhãn của bạn.

+1

hoàn hảo! đây là giải pháp đơn giản nhất – coolcool1994

+0

Đã không làm việc cho tôi. Nhãn vẫn bị mờ sau khi phóng to. –

3

Tôi đã triển khai giải pháp của Scrimmers bằng cách phân lớp UILabel là DetailUILabel bằng các phương thức ghi đè như thế này;

nhập khẩu QuartzCore

#import <QuartzCore/QuartzCore.h> 

phương pháp ghi đè init, initWithFrame nào bạn muốn.

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     CATiledLayer *tiledLayer = (CATiledLayer *)self.layer; 
     tiledLayer.levelsOfDetailBias = 4; 
     tiledLayer.levelsOfDetail = 4; 
     self.opaque = YES; 
    } 
    return self; 
} 

và layerClass, phương thức lớp học.

+ (Class)layerClass { 
    return [CATiledLayer class]; 
} 
+0

Điều này thật tuyệt vời! Cảm ơn bạn! –

1

Dưới đây là một cái gì đó mà tôi đã đưa ra:

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) { 
     label.font = UIFont(name: "YourFont", size: fontSize * scale) 
     label.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(1/scale, 1/scale), CGAffineTransformMakeRotation(0)) 
    } 

Cập nhật cho Swift 4.0:

func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) { 
    label.font = label.font.withSize(fontSize * scale) 
    label.transform = CGAffineTransform(scaleX: 1/scale, y: 1/scale).concatenating(CGAffineTransform(rotationAngle: 0)) 
} 

Và cũng hãy nhớ rằng nhãn phải đủ lớn để hiển thị toàn bộ văn bản. Đôi khi phải mất một chút để vẽ lại, nhưng phương pháp này khá đơn giản.

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