Простой способ поместить UIImage в UIButton
У меня есть UIButton в моем приложении для iPhone. Я установил его размер 100x100.
У меня есть изображение размером 400x200, которое я хочу отобразить на кнопке.
Кнопка STILL должна оставаться на уровне 100x100... и я хочу, чтобы изображение уменьшалось, чтобы оно соответствовало... но
сохраняйте правильное соотношение сторон.
Я подумал, что для этого используется "Aspect Fit".
Включить ли мое изображение с помощью setImage или setBackgroundImage?
Я устанавливаю AspectFit для кнопки? или изображение? или фоновое изображение?
(Мне нужны меньшие изображения, чтобы УВЕЛИЧИТЬ размер. В то время как большие изображения должны ОПИСАТЬ размер.
Всегда держать кнопку в 100x100.)
Я пробовал бесчисленные комбинации всех вышеперечисленных... и я просто не могу получить
все, чтобы работать в одно и то же время:
- Не изменяйте размер кнопки 100x100.
- Не разрушайте соотношение сторон изображения.
- Всегда увеличивайте маленькие изображения, чтобы они соответствовали кнопке.
- Всегда уменьшайте большие изображения, чтобы они соответствовали кнопке.
- Никогда не зажимайте ни один из краев изображения.
- Никогда не требуйте взлома "UIButtons over all your UIimages".
- Не нужно, чтобы все обновлялись до версии 4.1, чтобы использовать новые методы фреймворка.
Я вижу так много приложений, у которых так много полнофункциональных кнопок изображения... что я не могу поверить, что не могу понять эту очень простую, очень распространенную вещь.
Тьфу.
Ответы
Ответ 1
UIButton нарушен. Это короткий ответ. Свойства UIImageView
в его изображении и backgroundImage не учитывают настройки UIViewContentMode
. Они являются свойствами только для чтения, и в то время как содержимое UIImage
этих UIImageViews может быть установлено с помощью методов setImage:
и setBackgroundImage:
, режим содержимого не может быть.
Решение состоит либо в том, чтобы вначале создать нужные изображения в вашем комплекте, либо поместить UIImageView вниз, настроить его так, как вы хотите, а затем наложить на него ясную "пользовательскую" UIButton. Я обещаю, что взломал все эти фантастические профессиональные приложения, которые вы видели. Мы все должны это сделать.
Ответ 2
UIImage *img = [UIImage imageNamed:@"yourImageName"];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
[button setImage:img forState:UIControlStateNormal];
Ответ 3
Чтобы сделать это правильно, я бы фактически программным образом изменял размер и манипулировал изображением, чтобы получить желаемое соотношение сторон. Это позволяет избежать необходимости в любых хаках иерархии представлений, а также уменьшает любую производительность до одной операции, а не каждую перерисовку.
Этот (непроверенный) код должен помочь проиллюстрировать, что я имею в виду:
CGSize imageSize = image.size;
CGFloat currentAspect = imageSize.width / imageSize.height;
// for purposes of illustration
CGFloat targetWidth = 100;
CGFloat targetHeight = 100;
CGFloat targetAspect = targetWidth / targetHeight;
CGFloat newWidth, newHeight;
if (currentAspect > targetAspect) {
// width will end up at 100, height needs to be smaller
newWidth = targetWidth;
newHeight = targetWidth / currentAspect;
} else {
// height will end up at 100, width needs to be smaller
newHeight = targetHeight;
newWidth = targetHeight * currentAspect;
}
size_t bytesPerPixel = 4;
// although the image will be resized to { newWidth, newHeight }, it needs
// to be padded with empty space to provide the aspect fit behavior
//
// use calloc() to clear the data as it allocated
void *imageData = calloc(targetWidth * targetHeight, bytesPerPixel);
if (!imageData) {
// error out
return;
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (!colorSpace) {
// error out
return;
}
CGContextRef context = CGBitmapContextCreate(
imageData,
targetWidth,
targetHeight,
8, // bits per component
targetWidth * bytesPerPixel, // bytes per row
colorSpace,
kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst
);
CGColorSpaceRelease(colorSpace);
// now we have a context to draw the original image into
// in doing so, we want to center it, so prepare the geometry
CGRect drawRect = CGRectMake(
floor((targetWidth - newWidth) / 2),
floor((targetHeight - newHeight) / 2),
round(newWidth),
round(newHeight)
);
CGContextDrawImage(context, drawRect, image.CGImage);
// now that the bitmap context contains the aspect fit image with transparency
// letterboxing, we want to pull out a new image from it
CGImageRef newImage = CGBitmapContextCreateImage(context);
// destroy the temporary context
CGContextRelease(context);
free(imageData);
// and, finally, create a new UIImage
UIImage *newUIImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
Сообщите мне, если какая-либо часть этого неясно.
Ответ 4
Я думаю, что Дэн пытается сказать (но, не сказав этого), сделать это:
- Используйте "временное изображение" для изменения размера для вас.
- Временное изображение должно быть настроено на ASPECT FIT и HIDDEN.
- Убедитесь, что ваша кнопка настроена на нужный размер и НЕ установлена в ASPECT FIT.
// Make a frame the same size as your button
CGRect aFrame = CGRectMake(0, 0, myButton.frame.size.width, myButton.frame.size.height);
// Set your temp-image to the size of your button
imgTemp.frame = aFrame;
// Put your image into the temp-image
imgTemp.image = anImage;
// Copy that resized temp-image to your button
[myButton setBackgroundImage:tempImage forState:UIControlStateNormal];
Ответ 5
Поскольку ни одна из моих попыток не сработала...
Возможно, я должен попросить об этом. При использовании UIButton:
Когда я использую setImage вместо setBackgroundImage? (Почему есть оба?)
Когда я использую "Aspect Fit" вместо "Center"? (Почему обе кажутся растягивать мои изображения, когда я ожидаю, что они будут "сохранять пропорции" и "не изменять размер ничего", соответственно.)
И большой вопрос: почему такая распространенная вещь... такой огромный беспорядок?
Все это будет разрешено, если я найду способ обхода работы: просто используйте UIImage вместо этого и определите TAPS. (Но это, похоже, даже кошмар LARGER кода.)
Apple, если вы попытались упростить мою работу... вместо этого вы сделали это в 400 раз более запутанным.
Ответ 6
Поместите изображение через кнопку, установите изображение для изображения, а не для кнопки.
Все самое лучшее.
Ответ 7
Я бы изменил размер изображения до 100x100, поддерживая соотношение сторон содержимого, содержащегося в изображении. Затем установите для свойства backgroundImage UIButton изображение.
Ответ 8
Я столкнулся с той же проблемой несколько дней назад и решил ее. Пожалуйста, попробуйте с этим
[_profilePicBtn setImage:profilePic forState:UIControlStateNormal];
_profilePicBtn.imageView.contentMode = UIViewContentModeScaleAspectFit;