как предотвратить растягивание фонового изображения кнопки?

<p>я выделяю uibuttontypecustom uibutton для uiview с фоновым изображением, которое меньше, чем рамка кнопки. причина, по которой изображение меньше, заключается в том, что я пытаюсь добавить больше «целевой области» для кнопки uib. однако изображение масштабируется до полного размера кадра, а не только до размера изображения.</p><p>я попытался установить для свойства uibutton и uibutton imageview contentmode значение uiviewcontentmodescaleaspectfit, но не повезло, изображение все еще растягивается.</p><p>есть ли способ сделать то, что я пытаюсь сделать программно?</p><p>заранее спасибо!</p>

<p>многие люди совершают ту же ошибку, что и вы, в отношении изображений кнопок, а затем перепрыгивают через обручи, пытаясь заставить кнопку вести себя так, как они этого ожидают. давайте разберемся с этим раз и навсегда: </p><p><strong> у <code>uibutton</code> есть два типа изображений, которые он может отображать - изображение переднего плана и фоновое изображение </strong>. предполагается, что фоновое изображение кнопки заменит текстуру фона кнопки. таким образом, имеет смысл, что он <em>растягивается, чтобы заполнить весь фон</em>. однако<strong> изображение переднего плана кнопки, как ожидается, будет значком, который может отображаться или не отображаться рядом с текстом; это не будет растягиваться. </strong>\_ <em>может уменьшаться</em>, если рамка меньше изображения, но не будет растягиваться. вы даже можете установить выравнивание изображения переднего плана, используя свойства выравнивания элемента управления в интерфейсном разработчике.</p><p>передний план и фоновое изображение кнопки могут быть установлены в коде так:</p><pre><code>// stretchy [self setbackgroundimage:backgroundimage forstate:uicontrolstatenormal]; // not stretchy [self setimage:forgroundimage forstate:uicontrolstatenormal]; </code></pre>

<p>у вас нет доступа к фону imageview, <strong>, но есть полностью рабочий обходной путь:</strong></p><p><strong>edit</strong>: существует еще лучший обходной путь, чем тот, который я опубликовал изначально .. вы можете создать <strong>uiimage из любого цвета,</strong> и вызвать <code>-setbackgroundimage:forstate.</code></p><p>см. <code>bradley's</code> ответ, здесь: <a href="https://stackoverflow.com/a/20303841/1147286">https://stackoverflow.com/a/20303841/1147286</a> </p><hr><p>оригинальный ответ:</p><p>вместо вызова <code>-setbackgroundimage:forstate:</code> создайте новый uiimageview и добавьте его в качестве подпредставления кнопки.</p><pre><code>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]; </code></pre><ol> <li>создать изображение</li> <li>установите режим содержимого и фрейм</li> <li>я также установил узнаваемый тег, чтобы при повороте экрана я мог легко найти свой пользовательский imageview в подпредставлениях кнопки и сбросить ее рамку.</li> <li>добавьте это как подпредставление к кнопке</li> <li><strong>перенесите фронтальный вид изображения кнопки на передний план</strong>, чтобы наш пользовательский вид изображения не перекрывал его</li> </ol><p>когда кнопку нужно повернуть, просто найдите imageview по его тегу и сбросьте его рамку:</p><pre><code>uiimageview *bgimageview = (uiimageview *)[button viewwithtag:99]; [bgimageview setframe:cgrectmake(0, 0, newwidth, newheight)]; </code></pre>

<p>самый чистый и простой способ это, вероятно, использовать заголовки вставок кнопки.</p><p>вы устанавливаете свое изображение как изображение кнопки, а затем меняете левую вставку заголовка, чтобы она соответствовала минус ширине вашего изображения:</p><pre><code>mybutton.titleedgeinsets = uiedgeinsetsmake(0, -myimage.width, 0, 0) </code></pre><p>это переместит текст назад, где он был до того, как изображение было добавлено слева. вы также можете использовать это значение, чтобы добавить немного отступа к вашей кнопке.</p>

<p>наткнулся на эту проблему тоже. </p><p>добавление изображения программно, как подробно объясняет меммон, не помогло :( </p><p>у меня была кнопка 100x40 и изображение 100x100, оно выглядело сжатым, а не встроенным, как можно было бы сделать из опции «подгонка по размеру». на самом деле, ни один из этих вариантов просмотра не имел эффекта.</p><p>мне просто пришлось изменить его масштаб, чтобы он поместился на кнопке, а затем использовать setimage:</p><pre><code>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]; </code></pre>

<p>может помочь кому-то</p><pre><code>button.subviews.first?.contentmode = .scaleaspectfit </code></pre>

<p>еще одним соображением является ограничение baseline. если для ваших кнопок установлено это ограничение (отображаемое в виде горизонтальной или вертикальной линии через несколько элементов управления на макете), это приведет к растяжению ваших изображений без растяжения основного элемента управления кнопки. если ваша кнопка иным образом правильно ограничена (начальные/конечные и верхние/нижние пробелы и т.д.), удаление ограничения baseline не должно влиять на компоновку, в то же время позволяя изображению переднего плана масштабироваться должным образом до формы основной кнопки.</p>

<p>я предполагаю, что самое простое решение - использовать метод resizableimagewithcapinsets в uiimage. используйте uiedgeinsetsmake для настройки свободных мест.</p>