2012-03-28 33 views
15

Tôi cần căn chỉnh đường cơ sở của văn bản trong UILabels. Điều tôi đang làm là sắp xếp đường cơ sở của UILabels chứa văn bản và khi kích thước phông chữ trong hai nhãn khác nhau, kết quả này được căn chỉnh theo đường cơ sở UILabels nhưng đường căn bản không được căn lề (lệch bằng lề nhỏ, nhưng vẫn không đúng). Các nhãn được bao gồm trong một lớp con UIView tùy chỉnh, do đó self đề cập đến UIView bao gồm.Làm cách nào để căn chỉnh đường cơ sở của văn bản trong UILabels với kích thước phông chữ khác nhau trên iOS?

đây là mã có liên quan

[self.mySmallLabel sizeToFit]; 
[self.myBigLabel sizeToFit]; 

self.mySmallLabel.frame = CGRectMake(0,  
            self.bounds.size.height - self.mySmallLabel.bounds.size.height, 
            self.mySmallLabel.bounds.size.width, 
            self.mySmallLabel.bounds.size.height); 

self.myBigLabel.frame = CGRectMake(self.mySmallLabel.frame.origin.x + self.mySmallLabel.bounds.size.width, 
            self.bounds.size.height - self.myBigLabel.bounds.size.height, 
            self.myBigLabel.bounds.size.width, 
            self.myBigLabel.bounds.size.height); 
[self.mySmallLabel sizeToFit]; 
[self.myBigLabel sizeToFit]; 

Mã này kết quả trong aligment trong hình ảnh liên kết dưới đây.

Misalignemnt

Như bạn có thể thấy, mặc dù các đường cơ sở UILabel được liên kết, đường cơ sở của văn bản được lệch bằng lãi nhỏ. Làm thế nào tôi có thể căn chỉnh các đường cơ sở của văn bản động (vì kích thước phông chữ có thể thay đổi khi chạy)?

Trả lời

25

Tôi đã sử dụng this answer ở một vài nơi khác nhau, nhưng các đường cơ sở đôi khi là điểm ảnh trên màn hình Retina. Đoạn dưới đây chiếm quy mô của màn hình:

[majorLabel sizeToFit]; 
[minorLabel sizeToFit]; 

CGRect changedFrame = minorLabel.frame; 
changedFrame.origin.x = CGRectGetWidth(majorLabel.frame); 

const CGFloat scale = [UIScreen mainScreen].scale; 
const CGFloat majorLabelBaselineInSuperView = CGRectGetMaxY(majorLabel.frame) + majorLabel.font.descender; 
const CGFloat minorLabelBaselineInOwnView = CGRectGetHeight(minorLabel.frame) + minorLabel.font.descender; 
changedFrame.origin.y = ceil((majorLabelBaselineInSuperView - minorLabelBaselineInOwnView) * scale)/scale; 

minorLabel.frame = changedFrame; 
+4

Bất kỳ phiên bản nào sử dụng bố cục tự động? – adib

+9

Phiên bản bố cục tự động rất dễ dàng: chỉ cần căn chỉnh hai nhãn bằng 'NSLayoutAttributeBaseline' (hoặc' NSLayoutAttributeLastBaseline' hoặc 'NSLayoutAttributeFirstBaseline', tùy thuộc vào những gì bạn đang làm). –

3

Tôi đang tìm cách tự mình thực hiện việc này (vừa nãy) và tìm thấy câu trả lời của mình trên số almost identical question. Nó không phải là giải pháp đơn giản, mặc dù chúng ta phải làm toán.

Tôi chỉ cần làm điều đó với 2 nhãn khác nhau và tôi đang làm điều đó trong một phân lớp của UIView.

- (void)layoutSubviews { 
    [majorLabel sizeToFit]; 
    [minorLabel sizeToFit]; 

    CGRect changedFrame = minorLabel.frame; 
    changedFrame.origin.x = majorLabel.frame.size.width; 
    changedFrame.origin.y = (majorLabel.frame.size.height + majorLabel.font.descender) - (minorLabel.frame.size.height + minorLabel.font.descender); 
    minorLabel.frame = changedFrame; 
} 
8

Bạn có thể nhận được sự liên kết cơ sở pixel hoàn hảo cho bất kỳ cặp UILabels bằng cách sử dụng giá trị Ascender UIFont trong một phép tính đơn giản. Dưới đây là cách thực hiện:

[majorLabel sizeToFit]; 
[minorLabel sizeToFit]; 

CGRect changedFrame = minorLabel.frame; 
changedFrame.origin.y = ceilf(majorLabel.frame.origin.y + (majorLabel.font.ascender - minorLabel.font.ascender)); 
minorLabel.frame = changedFrame; 

ceilf() được sử dụng vì giá trị phông chữ có thể phân số.

Tôi đã thử nghiệm điều này trên cả hai thiết bị võng mạc và không võng mạc, với kết quả xuất sắc. Định vị hai nhãn tương đối với nhau trên trục x đã bị bỏ qua, vì nhu cầu của bạn có thể thay đổi. Nếu bạn cần một giải thích nhanh về những gì UIFont ascender là (cộng với thông tin UIFont khác) hãy kiểm tra rõ ràng, súc tích article này.

+0

tôi đã thử điều này, nhưng, trong thử nghiệm của tôi trên iOS5 ascender và descender đều là 0 –

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