как установить состояние uibutton, которое будет выделено после нажатия на него

<p>у меня есть типичное требование, при котором мне нужно держать кнопку в выделенном состоянии после ее нажатия. мне нужно выполнить задачу, которая должна работать только тогда, когда кнопка находится в подсвеченном состоянии. на самом деле я устанавливаю состояние кнопки для подсветки программно. </p><p><code>[sender sethighlighted:yes];</code> </p><p>и как только кнопка находится в подсвеченном состоянии, мне нужно выполнить другое действие. </p><pre><code>- (ibaction)changestate: (uibutton*)sender { if (sender.highlighted == yes) { [self performsomeation:sender]; } } </code></pre><p>но, к моему ужасу, всякий раз, когда я нажимаю любую кнопку, вышеуказанное условие становится истинным, и действие выполняется неоднократно. есть ли способ, которым я могу сохранить состояние uibutton после его нажатия?</p><p><strong>edit</strong>- на самом деле мне нужно выполнить 3 разных действия для 3 разных состояний кнопки. я уже использую выбранное состояние и нормальное состояние. теперь мне нужно использовать выделенное состояние.</p>

<pre><code>[sender setselected:yes]; </code></pre><p>или вы можете смоделировать этот эффект двумя изображениями для вашей uibutton (<code>notselectedimage.png</code> и <code>selectedimage.png</code>), а затем отслеживать состояние кнопки с помощью переменной bool, такой как <code>bool buttoncurrentstatus;</code>. тогда в .h файле:</p><pre><code>bool buttoncurrentstatus; </code></pre><p>и в .m файле</p><pre><code>// connect this method with touchupinside function - (ibaction)changestate:(uibutton*)sender { /* if we have multiple buttons, then we can differentiate them by tag value of button.*/ // but note that you have to set the tag value before use this method. if([sender tag] == yourbuttontag){ if (buttoncurrentstatus == no) { buttoncurrentstatus = yes; [butt setimage: [uiimage imagenamed:@"selectedimage.png"] forstate:uicontrolstatenormal]; //[self performsomeaction:sender]; } else { buttoncurrentstatus = no; [butt setimage:[uiimage imagenamed:@"notselectedimage.png"] forstate:uicontrolstatenormal]; //[self performsomeaction:sender]; } } } </code></pre>

<pre><code>- (void)mybutton:(id)sender { uibutton *button = (uibutton *)sender; button.selected = ![button isselected]; // important line if (button.selected) { nslog(@"selected"); nslog(@"%i",button.tag); } else { nslog(@"un selected"); nslog(@"%i",button.tag); } } </code></pre>

<p>выделенное состояние используется для выделения кнопки<em> во время </em>к ней прикасается. событие касания в кнопке выделяет его. вместо этого вы должны использовать «выбранное» состояние. </p><p>если вы хотите выполнить действие после нажатия кнопки, не присоединяйте свой метод к событию изменения состояния, присоединяйте свой метод к событию touchupinside.</p>

<p>я просто нахожу способ, поэтому я делюсь им, на всякий случай ...</p><p>я сохранил свою uibutton и установил одно изображение для каждого состояния (чтобы вы могли перейти к кнопке с 4 состояниями) . я установил userinteractionenabled на no -> эта кнопка не получит никакого прикосновения . цель эта первая кнопка, чтобы показать состояние</p><p>я создаю второй пользовательский uibutton с тем же кадром, что и первый. для этого ни одно изображение не будет установлено для состояния (это полностью прозрачная кнопка). цель этой кнопки - поймать событие касания. поэтому я добавил цель к этой кнопке в событии touchupinside. и затем, когда событие срабатывает, я меняю состояние первой кнопки на отключено, выделено, выбрано или ни на одно из этих состояний (= состояние по умолчанию).</p><p>все работает как шарм!</p>

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

<p>используйте <code>[sender setselected: yes];</code>, я думаю, это будет полезно для вас.</p>

<p>только для ios 7: вам следует рассмотреть возможность установки для параметра rendermode изображения значения uiimagerenderingmodealwaystemplate. затем вы можете использовать tintcolor для представления различных состояний. </p><p>см. <a href="https://stackoverflow.com/questions/19802982/apply-tintcolor-to-uiimage">как применить tintcolor к uiimage?</a> а также </p><p>см. <a href="https://stackoverflow.com/questions/8389193/tint-a-uiview-with-all-its-subviews">подкрасить uiview со всеми его подпредставлениями</a> </p>

<p>согласно apple, uibutton обладает свойством <a href="https://developer.apple.com/library/ios/documentation/uikit/reference/uibutton\_class/#//apple\_ref/occ/instp/uibutton/imageview">imageview</a> :</p><blockquote> <p>хотя это свойство доступно только для чтения, <strong>его собственные свойства доступны для чтения/записи.</strong> используйте эти свойства, чтобы настроить внешний вид и поведение вида кнопки.</p> </blockquote><p>это означает, что вы можете установить в ib (в раскадровке) изображение для этой кнопки и установить выделенное изображение:</p><ol> <li>откройте инспектор атрибутов.</li> <li>в разделе <strong>button</strong> выберите изображение.</li> <li>в том же разделе измените конфигурацию состояния на выделенное. обратите внимание, что изображение, которое вы выбрали по умолчанию, теперь исчезло, и теперь вы можете установить новое изображение для выделения.</li> <li>теперь у вас есть кнопка с 2 состояниями конфигурации и все, что вам нужно сделать во время выполнения, чтобы изменить <code>button.highlighted = true</code>. кроме того, проверьте <a href="https://developer.apple.com/library/ios/documentation/uikit/reference/uicontrol\_class/">uicontrol</a> в <em>настройка атрибутов элемента управления</em> для получения дополнительных состояний.</li> </ol><p>вы также можете сделать это программно следующим образом:</p><p><strong>swift (и почти то же самое в objective-c):</strong></p><pre><code>// setting the highlighted image self.somebutton.imageview?.highlightedimage = uiimage(named: "imagenamefromimageassest") // somebutton will now some the highlighted image and not the image set in the ib self.somebutton.imageview?.highlighted = true </code></pre>

<pre><code>uibutton *btn\_tmp=sender; if(!(btn\_tmp.selected)) { [btn\_temp sethighlighted:yes]; } </code></pre>

<p>решение сложно, но возможно.</p><p>проблема в том, что вы пытались изменить выделенный статус в методе действия кнопки, который, как я полагаю, выполняет очистку или проверку в конце действия и переключает выделенный статус. когда вы пытаетесь отладить его, вы получаете выделенный = 1, но в конце он изменится.</p><p>странно, но ваша «кнопка 3 статусов» иногда полезна, когда вы хотите удерживать кнопку в «выделенном» режиме, например, в «выбранном» режиме, чтобы получить различное действие в зависимости от 3 статусов…. единственная проблема, которую вы не удалось проанализировать это или переключить его в подсвеченный режим в методе действия кнопки, так как он сразу переключится в подсвеченный режим, когда пользователь нажмет и вернет его в конце.</p><p>решение использует отправку.</p><pre><code>dispatch\_time\_t poptime = dispatch\_time(dispatch\_time\_now, 0.1 * nsec\_per\_sec); dispatch\_after(poptime, dispatch\_get\_main\_queue(), ^(void){ [thebutton sethighlighted:yes]; }); </code></pre><p>это сделает свое дело, и вы можете использовать 3 статуса.</p>