какао touch: как изменить цвет и толщину границы uiview?

<p>я видел в инспекторе, что я могу изменить цвет фона, но я хотел бы также изменить цвет и толщину границы, возможно ли это?</p><p>спасибо</p>

<p>вы должны использовать слой вида, чтобы установить свойство границы. например:</p><pre><code>#import <quartzcore/quartzcore.h> ... view.layer.bordercolor = [uicolor redcolor].cgcolor; view.layer.borderwidth = 3.0f; </code></pre><p>вам также нужно связаться с quartzcore.framework для доступа к этой функции.</p>

<h2>xcode 6 обновление</h2><p>начиная с последней версии xcode, есть лучшее решение для этого:</p><p>с <code>@ibinspectable</code> вы можете установить атрибуты непосредственно из <em>внутри</em> <code>attributes inspector</code>.</p><p><img src="https://i.stack.imgur.com/vuoku.gif" alt="my custom view @ibinspectable attributes"></p><p>это устанавливает <code>user defined runtime attributes</code> для вас:</p><p><img src="https://i.stack.imgur.com/2nxio.gif" alt="enter image description here"></p><p>есть два подхода к настройке:</p><p><strong> вариант 1 </strong>(с живым обновлением в раскадровке)</p><ol> <li>создать <code>mycustomview</code>.</li> <li>это наследуется от <code>uiview</code>.</li> <li>установите <code>@ibdesignable</code> (это сделает обновление view активным). *</li> <li>установите свои атрибуты времени выполнения (границы и т.д.) с помощью <code>@ibinspectable</code></li> <li>измените класс просмотров на <code>mycustomview</code></li> <li>отредактируйте в панели атрибутов и посмотрите изменения в раскадровке :)</li> </ol><p>`</p><pre><code>@ibdesignable class mycustomview: uiview { @ibinspectable var cornerradius: cgfloat = 0 { didset { layer.cornerradius = cornerradius layer.maskstobounds = cornerradius > 0 } } @ibinspectable var borderwidth: cgfloat = 0 { didset { layer.borderwidth = borderwidth } } @ibinspectable var bordercolor: uicolor? { didset { layer.bordercolor = bordercolor?.cgcolor } } } </code></pre><p>* <code>@ibdesignable</code> работает только при установке в начале <code>class mycustomview</code></p><p><strong> вариант 2 </strong>(не работает с swift 1.2, см. комментарии)</p><p>расширьте свой класс uiview:</p><pre><code>extension uiview { @ibinspectable var cornerradius: cgfloat = 0 { didset { layer.cornerradius = cornerradius layer.maskstobounds = cornerradius > 0 } } @ibinspectable var borderwidth: cgfloat = 0 { didset { layer.borderwidth = borderwidth } } @ibinspectable var bordercolor: uicolor? { didset { layer.bordercolor = bordercolor?.cgcolor } } } </code></pre><p>таким образом, ваш вид по умолчанию <em>always</em> имеет эти дополнительные редактируемые поля в <code>attributes inspector</code>. еще одним преимуществом является то, что вам не нужно каждый раз менять класс на <code>mycustomview</code> ... однако одним из недостатков этого является то, что вы увидите изменения только при запуске приложения.</p>

<p>вы также можете создать рамку с цветом вашего желания.</p><pre><code>view.layer.bordercolor = [uicolor colorwithred:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].cgcolor; </code></pre><p>* r, g, b - значения от 0 до 255.</p>

<p>добавьте следующие @ibinspectables в расширение uiview</p><pre><code>extension uiview { @ibinspectable var borderwidth: cgfloat { get { return layer.borderwidth } set(newvalue) { layer.borderwidth = newvalue } } @ibinspectable var bordercolor: uicolor? { get { if let color = layer.bordercolor { return uicolor(cgcolor: color) } return nil } set(newvalue) { layer.bordercolor = newvalue?.cgcolor } } } </code></pre><p>и тогда вы сможете установить атрибуты bordercolor и borderwidth непосредственно из инспектора атрибутов. смотрите прикрепленное изображение</p><p> <a href="http://i.stack.imgur.com/q52cc.png">инспектор атрибутов</a> </p>

<p>когда я использую решение calayer владимира, и в верхней части представления у меня есть анимация, например, модальное отключение uinavigationcontroller, я вижу много глюков, которые имеют проблемы с производительностью при рисовании.</p><p>итак, еще один способ добиться этого, но без сбоев и потери производительности, - создать пользовательский uiview и реализовать сообщение <code>drawrect</code>, например, так:</p><pre><code>- (void)drawrect:(cgrect)rect { cgcontextref contextref = uigraphicsgetcurrentcontext(); cgcontextsetlinewidth(contextref, 1); cgcontextsetrgbstrokecolor(contextref, 255.0, 255.0, 255.0, 1.0); cgcontextstrokerect(contextref, rect); } </code></pre>

<pre><code>view.layer.borderwidth = 1.0 view.layer.bordercolor = uicolor.lightgray.cgcolor </code></pre>

<p>попробуйте этот код:</p><pre><code>view.layer.bordercolor = [uicolor redcolor].cgcolor; view.layer.borderwidth= 2.0; [view setclipstobounds:yes]; </code></pre>

<p>я бы не советовал переопределять drawrect из-за снижения производительности.</p><p>вместо этого я бы изменил свойства класса, как показано ниже (в вашем пользовательском интерфейсе):</p><pre><code> - (id)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { self.layer.borderwidth = 2.f; self.layer.bordercolor = [uicolor redcolor].cgcolor; } return self; </code></pre><p>я не видел никаких глюков при использовании вышеуказанного подхода - не уверен, почему включение initwithframe останавливает это ;-)</p>

<p>@ibinspectable работает для меня на ios 9, swift 2.0</p><pre><code>extension uiview { @ibinspectable var borderwidth: cgfloat { get { return layer.borderwidth } set(newvalue) { layer.borderwidth = newvalue } } @ibinspectable var cornerradius: cgfloat { get { return layer.cornerradius } set(newvalue) { layer.cornerradius = newvalue } } @ibinspectable var bordercolor: uicolor? { get { if let color = layer.bordercolor { return uicolor(cgcolor: color) } return nil } set(newvalue) { layer.bordercolor = newvalue?.cgcolor } } </code></pre>

<p>я хотел добавить это к ответу @ marczking (<strong> вариант 1 </strong>) в качестве комментария, но мой скромный статус в stackoverflow препятствует этому.</p><p>я сделал ответ @ marczking на objective c. работает как шарм, спасибо @marczking!</p><p>uiview + border.h:</p><pre><code>#import <uikit/uikit.h> ib\_designable @interface uiview (border) -(void)setbordercolor:(uicolor *)color; -(void)setborderwidth:(cgfloat)width; -(void)setcornerradius:(cgfloat)radius; @end </code></pre><p>uiview + border.m:</p><pre><code>#import "uiview+border.h" @implementation uiview (border) // note: cannot use synthesize in a category -(void)setbordercolor:(uicolor *)color { self.layer.bordercolor = color.cgcolor; } -(void)setborderwidth:(cgfloat)width { self.layer.borderwidth = width; } -(void)setcornerradius:(cgfloat)radius { self.layer.cornerradius = radius; self.layer.maskstobounds = radius > 0; } @end </code></pre>

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

<p>если вы хотите добавить разные границы на разных сторонах, возможно, добавьте подпредставление с определенным стилем, способ легко придумать.</p>

<p>цвет границы элемента в swift 4.2:</p><pre><code>let cell = tableview.dequeuereusablecell(withidentifier: "cell\_lastorderid") as! cell\_lastorder cell.layer.borderwidth = 1 cell.layer.bordercolor = uicolor.white.cgcolor cell.layer.cornerradius = 10 </code></pre>