2011-12-30 33 views
47

Tôi đang phân bổ UIButtonTypeCustom UIButton cho UIView với hình nền nhỏ hơn khung của nút. Lý do tại sao hình ảnh nhỏ hơn là bởi vì tôi đang cố gắng thêm nhiều hơn một "khu vực mục tiêu" cho UIButton. Tuy nhiên, hình ảnh đang được thu nhỏ với kích thước đầy đủ của khung hình, thay vì chỉ là kích thước của hình ảnh.Làm cách nào để ngăn hình ảnh nền của nút kéo giãn?

Tôi đã thử đặt thuộc tính contentView của UIButton và UIButton imageView contentMode thành "UIViewContentModeScaleAspectFit", nhưng không may mắn, hình ảnh vẫn bị kéo dài.

Có cách nào để làm những gì tôi đang cố gắng lập trình không?

Cảm ơn trước!

+4

Bạn có thực sự cần nó để được hình nền ? Bạn có cần thực sự viết văn bản hoặc đặt một hình ảnh khác lên trên nó không? Nếu không, hãy sử dụng hình ảnh chứ không phải hình nền, vì chỉ hình nền được kéo dài theo mặc định để khớp với khung. –

+0

@Raphael Không có câu nào trong số những câu trả lời này có phù hợp không? – memmons

Trả lời

-2

Những gì bạn cần làm là thêm hình ảnh của bạn dưới dạng UIImageView.

Thêm nút bằng nền có chiều ngang (UIColor ClearColor) lên trên cùng với chiều rộng và chiều cao mong muốn của bạn.

+0

Đó thực sự là một gợi ý xấu, vì hình ảnh sẽ không là một phần của nút và sẽ không phản ánh các thay đổi trạng thái (sẽ đánh bại mục đích của việc có một hình ảnh như một phần của nút). – GtotheB

+0

Để bạn có thể thay đổi hình ảnh khi nút được nhấn để bắt chước thay đổi trạng thái – ozba

+0

@ozba Thay đổi trạng thái cho hình ảnh đã được hỗ trợ trên nút. Thêm một hình nền phía sau một nút rõ ràng để bắt chước một nút có hình ảnh gần như không bao giờ là ý tưởng hay và thường là một ý tưởng tồi tệ. – memmons

120

Rất nhiều người mắc phải lỗi tương tự bạn làm liên quan đến hình ảnh nút và sau đó nhảy qua hoops cố gắng làm cho nút hoạt động như mong đợi. Hãy xóa điều này một lần và cho tất cả:

A UIButton có hai loại hình ảnh có thể hiển thị - hình ảnh nền trước và hình nền. Hình nền cho một nút được dự kiến ​​sẽ thay thế kết cấu nền của nút. Như vậy, có nghĩa là nó trải dài để lấp đầy toàn bộ nền. Tuy nhiên, hình ảnh nền trước của nút được mong đợi là một biểu tượng có thể hoặc không thể hiển thị cùng với văn bản; nó sẽ không căng ra.có thể thu nhỏ nếu khung hình nhỏ hơn hình ảnh nhưng khung hình sẽ không kéo dài. Bạn thậm chí có thể thiết lập sự liên kết của hình ảnh nền trước bằng cách sử dụng các thuộc tính Căn chỉnh điều khiển trong Trình tạo giao diện.

ảnh foreground và background của một nút có thể được thiết lập trong mã như thế này:

// stretchy 
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal]; 

// not stretchy 
[self setImage:forgroundImage forState:UIControlStateNormal]; 
+49

Bạn sẽ làm gì khi bạn cần một hình ảnh không kéo dài được hiển thị với văn bản ở trên cùng của nó? –

+0

Thật kỳ lạ, bất cứ khi nào tôi đặt thuộc tính hình ảnh UIButton, văn bản tiêu đề biến mất. Có cách nào để ngăn chặn điều đó không? chỉnh sửa: Oh, văn bản là tắt bên phải .. lạ, tôi đoán tôi sẽ chỉ chơi với các điều chỉnh cho đến khi nó là trực tiếp dưới hình ảnh tiền cảnh – powerj1984

+0

@ powerj1984 Nếu bạn muốn văn bản ngồi trên đầu trang của một hình ảnh, bạn nên sử dụng backgroundImage. Hình ảnh nền trước được dự kiến ​​sẽ thay thế văn bản hoặc ngồi bên cạnh văn bản. Nếu bạn đang điều chỉnh văn bản của bạn để buộc nó ngồi trên đầu trang của hình ảnh tiền cảnh bạn đang làm nó sai. – memmons

0

xem xét khác là hạn chế cơ bản. Nếu các nút của bạn có bộ hạn chế này (được mô tả như một đường ngang hoặc dọc thông qua nhiều điều khiển trên bố cục của bạn), nó sẽ làm cho hình ảnh của bạn giãn ra mà không kéo dài nút điều khiển bên dưới. Nếu nút của bạn bị ràng buộc đúng cách (không gian đầu/cuối và trên cùng/dưới cùng, v.v.), việc loại bỏ ràng buộc BaseLine sẽ không ảnh hưởng đến bố cục, trong khi cho phép hình ảnh nền trước đúng tỷ lệ với hình dạng nút bên dưới.

-1

Answerbot trả lời câu hỏi bằng những gì là đúng và chính xác để thực hiện. Đừng chống lại hệ điều hành và sử dụng những thứ như dự định luôn là lời khuyên tốt. Tuy nhiên, đôi khi bạn cần phải phá vỡ các quy tắc.

Tôi đã có thể che dấu hình nền mở rộng (không ngăn chặn nó) bằng cách phủ nó với một lớp màu đen sau đó chồng lên một lần nữa với một hình ảnh được thay đổi kích thước đúng. Điều này được thực hiện bằng cách tạo một lớp con của UIButton và ghi đè phương thức setHighlighted.

MÃ CẦN?

- (void)setHighlighted:(BOOL)highlighted 
{ 
super.highlighted = highlighted; 

// 
//Whenever an image needs to be highlighted, create a dimmed new image that is correctly  sized. Below it is a englarged stretched image. 
// 
if (highlighted != _previousHighlightedSate) 
{ 
    _previousHighlightedSate = highlighted; 

    if (highlighted) 
    { 
     //Create a black layer so image can dim 
     _blackLayer = [CALayer layer]; 
     _blackLayer.bounds = self.bounds; 
     CGRect rect = _blackLayer.bounds; 
     rect.size.width = rect.size.width*2; 
     rect.size.height = rect.size.height*2; 
     _blackLayer.bounds = rect; 
     _blackLayer.backgroundColor = [[UIColor blackColor] CGColor]; 

     //create image layer 
     _nonStretchImageLayer = [CALayer layer]; 
     _nonStretchImageLayer.backgroundColor = [UIColor blackColor].CGColor; 
     _nonStretchImageLayer.bounds = CGRectMake(0 , 0, self.bounds.size.width, self.bounds.size.height); 
     _nonStretchImageLayer.frame = CGRectMake(0 , 0, self.bounds.size.width, self.bounds.size.height); 
     _nonStretchImageLayer.contentsGravity = kCAGravityResizeAspect;//default is to resize 
     _nonStretchImageLayer.contents = (id)self.imageView.image.CGImage; 
     _nonStretchImageLayer.opacity = 0.5; 

     //add layers to image view 
     [self.imageView.layer addSublayer:_blackLayer]; 
     [self.imageView.layer addSublayer:_nonStretchImageLayer]; 
    } 
    else 
    { 
     //remove from image view 
     [_blackLayer removeFromSuperlayer]; 
     [_nonStretchImageLayer removeFromSuperlayer]; 

     //nil them out. 
     _blackLayer = nil; 
     _nonStretchImageLayer = nil; 
    } 
} 

Cảm hứng cho công việc này xung quanh đến từ here

0

Tôi đoán là giải pháp đơn giản nhất là sử dụng phương pháp resizableImageWithCapInsets UIImage của. Sử dụng UIEdgeInsetsMake để cấu hình các không gian trống.

1

Cách sạch nhất và dễ nhất có thể là sử dụng các phần tử tiêu đề của nút.

Bạn đặt hình ảnh của bạn như hình ảnh nút, và sau đó bạn thay đổi hình chữ nhật tiêu đề còn lại để phù hợp trừ đi chiều rộng của hình ảnh của bạn:

myButton.titleEdgeInsets = UIEdgeInsetsMake(0, -myImage.width, 0, 0) 

này sẽ di chuyển các văn bản trở lại nơi nó được trước khi hình ảnh đã thêm vào bên trái của nó. Bạn cũng có thể sử dụng giá trị này để thêm một số padding cho bạn nút.

6

Bạn không cần phải truy cập vào các IMAGExem nền, nhưng có đầy đủ là cách giải quyết lao động:

EDIT: Có một cách giải quyết tốt hơn sau đó những gì tôi gửi ban đầu. Bạn có thể tạo một UIImage từ bất kỳ màu sắc, và gọi -setBackgroundImage:forState.

Xem bradley's câu trả lời, ở đây: https://stackoverflow.com/a/20303841/1147286


Original câu trả lời:

Thay vì gọi -setBackgroundImage:forState:, tạo một UIImageView mới và thêm nó như là một subview của nút.

UIImageView *bgImageView = [[UIImageView alloc] initWithImage:img]; 
bgImageView.contentMode = UIViewContentModeScaleAspectFit; 
[bgImageView setFrame:CGRectMake(0, 0, videoButton.frame.size.width, videoButton.frame.size.height)]; 
bgImageView.tag = 99; 
[yourButton addSubview:bgImageView]; 
[yourButton bringSubviewToFront:yourButton.imageView]; 
  1. Tạo các ImageView
  2. Đặt chế độ nội dung và khung
  3. Tôi cũng thiết lập một thẻ nhận biết, do đó khi màn hình xoay tôi có thể dễ dàng tìm thấy IMAGExem tùy chỉnh của tôi trong subviews của nút và đặt lại khung của nó
  4. Thêm dưới dạng chế độ xem phụ vào nút
  5. Mang hình ảnh mặt trướcXem nút về phía trước do đó, imageView tùy chỉnh của chúng tôi không chồng chéo lên

Khi nút cần phải xoay chỉ tìm ra IMAGExem bằng thẻ của mình và đặt lại khung của nó:

UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99]; 
[bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)]; 
0

vấp vào vấn đề này quá.

Thêm hình ảnh theo chương trình, như memmons giải thích kỹ lưỡng, đã không giúp đỡ :(

Tôi đã có một nút 100x40 và hình ảnh 100x100, nó sẽ xuất hiện vắt, không được trang bị, như người ta sẽ suy ra từ "Aspect Fit" tùy chọn. Trên thực tế, không có tùy chọn chế độ xem nào có hiệu lực.

Tôi chỉ phải rescale nó để nó sẽ phù hợp vào một nút, sau đó sử dụng setImage:

UIImage *img=[UIImage imageNamed:@"myimage.png"]; 
CGImageRef imgRef = [img CGImage]; 
CGFloat imgW = CGImageGetWidth(imgRef); 
CGFloat imgH = CGImageGetHeight(imgRef); 
CGFloat btnW = myBttn.frame.size.width; 
CGFloat btnH = myBttn.frame.size.height; 
//get lesser button dimension 
CGFloat minBtn=btnW; 
if (btnW>btnH) { 
    minBtn=btnH; 
} 
//calculate scale using greater image dimension 
CGFloat scl=imgH/minBtn; 
if (imgW>imgH) { 
    scl=imgW/minBtn; 
} 
//scale image 
UIImage *scaledImage = [UIImage imageWithCGImage:[img CGImage] scale:(img.scale * scl) orientation:(img.imageOrientation)]; 
//clean up 
UIGraphicsEndImageContext(); 
//set it on a button 
[myBttn setImage:scaledImage forState:UIControlStateNormal]; 
-1

Nó là đơn giản như:

ImageBn.imageView?.contentMode = .scaleAspectFit 
    ImageBn.setImage(chosenImage, for: .normal) 
Các vấn đề liên quan