UIBUTTON и вид сборщика - PullRequest
3 голосов
/ 21 июня 2011

Я хочу отобразить средство выбора, когда пользователь нажимает кнопку Я переклассифицировал UIButton и изменил его входное представление так, чтобы оно было доступно для записи.

Я перешел по этой ссылке http://nomtek.com/tips-for-developers/working-with-pickers/

Я нажимаю на кнопку, и ничего не происходит. Если я изменю представление ввода с кнопки на UITextField, то это прекрасно работает. Какие-нибудь мысли? Спасибо Саро

Ответы [ 3 ]

4 голосов
/ 10 марта 2015

1) Создание подкласса UIButton

.h

#import <UIKit/UIKit.h>

@interface UIButtonAsFirstResponder : UIButton

@property (strong, nonatomic) UIView *inputView;
@property (strong, nonatomic) UIView *inputAccessoryView;

@end

.m

#import "UIButtonAsFirstResponder.h"

@implementation UIButtonAsFirstResponder

- (BOOL) canBecomeFirstResponder
{
    return YES;
}

@end

2) Set inputView (при необходимости также inputAccessoryView) в вашем контроллере вида (на ваш инструмент выбора или любой другой пользовательский вид)

3) Создайте IBAction для вашей кнопки в контроллере вида

- (IBAction)becom:(id)sender {
    [sender becomeFirstResponder];
}

Если вы хотите удалить клавиатурупозвоните по вашей кнопке:

[button resignFirstResponder];

или в поле зрения контроллера:

[self.view endEditing:YES];
2 голосов
/ 31 января 2017

Вот как я это сделал в Swift 3 (правила для переопределения свойств отличаются от Objective-C).

Мне нужна кнопка, которая отображает дату и отображает средство выбора даты в нижней части экрана при нажатии кнопки, чтобы позволить пользователю редактировать отображаемую дату.Это относительно легко сделать с помощью всплывающего окна, привязанного к целевой кнопке, но мое приложение предназначено только для iPhone (не для iPad), поэтому шаблон UITextField-inputView выглядит лучше ( используйте в приложениях AppStore на свой страх и риск нарушения прав человека.Руководство по интерфейсу ).

Подкласс кнопок:

class EditableButton: UIButton {

    // This holds the assigned input view (superclass property is readonly)
    private var customInputView: UIView?

    // We override the superclass property as computed, and actually 
    // store into customInputView: 
    override var inputView: UIView? {
        get {
            return customInputView
        }
        set (newValue) {
            customInputView = newValue
        }
    }

    // Must be able to become first responder in order to 
    // get input view to be displayed:
    override var canBecomeFirstResponder: Bool {
        return true
    }

    // Setup becoming first responder on tap:
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.addTarget(self, action: #selector(EditableButton.tap(_:)), for: .touchDown)
        // (Not sure if this creates a retain cycle; must investigate)
    }

    @IBAction func tap(_ sender: UIButton) {
        self.becomeFirstResponder()
    }
} 

Просмотр кода контроллера:

class ViewController: UIViewController {

    // Set the appropriate subclass in the storyboard too!
    @IBOutlet weak var todayButton: EditableButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let datePicker = UIDatePicker()
        datePicker.datePickerMode = .date
        todayButton.inputView = datePicker

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        todayButton.setTitle(dateFormatter.string(from: Date()), for: .normal)

        // Also hook an a target/action to the date picker's 
        // valueChanged event, to get notified of the user's input
        datePicker.addTarget(self, action: #selector(ViewController.changeDate(_:)), for: .valueChanged)
    }

    @IBAction func changeDate(_ sender: UIDatePicker) {
        // (update button title with formatted date)
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        todayButton.setTitle(dateFormatter.string(from: sender.date), for: .normal)  

        // Dismiss picker:
        todayButton.resignFirstResponder()
    }
}

Примечание: Для простоты этоКод отклонит средство выбора даты, как только будет указана дата -ie, когда вы прокручиваете любое из колес.Это может быть не то, что вам нужно: как правило, пользователь указывает дату по одному компоненту за раз (год, месяц и т. Д.).Эта реализация не позволит пользователю завершить указание всех компонентов даты до закрытия средства выбора даты.

В идеале вы бы добавили UIToolbar в качестве вида вспомогательного ввода со словом "done"msgstr "кнопка, которая отклоняет представление ввода (т. е. вызывает отставку кнопки первого респондента).Это потребовало бы дальнейшей модификации подкласса UIButton (чтобы также разместить inputAccessoryView), но должно быть выполнимым.


EDIT: Я могу подтвердить, что представление вспомогательного ввода также может бытьприкрепленный к пользовательскому подклассу UIButton точно так же, как и представление ввода:

private var customInputAccessoryView: UIView?

override var inputAccessoryView: UIView? {
    get {
        return customInputAccessoryView
    }
    set (newValue) {
        customInputAccessoryView = newValue
    }
}

Теперь я настроил его так:

let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
todayButton.inputView = datePicker

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
todayButton.setTitle(dateFormatter.string(from: Date()), for: .normal)

datePicker.addTarget(self, action: #selector(ViewController.changeDate(_:)), for: .valueChanged)

let dateToolbar = UIToolbar(frame: CGRect.zero)
dateToolbar.barStyle = .default

let dateDoneButton = UIBarButtonItem(
        barButtonSystemItem: .done,
        target: self,
        action: #selector(ViewController.dateDone(_:)))
let dateSpacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

dateToolbar.items = [dateSpacer, dateDoneButton]
dateToolbar.sizeToFit()
todayButton.inputAccessoryView = dateToolbar

И ответим двумя отдельными действиями:

@IBAction func changeDate(_ sender: UIDatePicker) {
    // Update button title in real time:
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    todayButton.setTitle(dateFormatter.string(from: sender.date), for: .normal)
}

@IBAction func dateDone(_ sender: UIBarButtonItem) {
    // ...but dismiss picker only on 'Done': 
    todayButton.resignFirstResponder()
}

Также , метод deinit() моего подкласса пользовательских кнопок вызывается, когда контроллер представления отключен от навигации, поэтому либо UIButton больше не (?)сохраняет свои цели, или среда выполнения Swift умнее, чем я думал ...


ОБНОВЛЕНИЕ: Я собрал проект Xcode, демонстрирующий эту пользовательскую кнопку (Github репозиторий).Это должно быть довольно просто изменить его для работы с пользовательским UIPickerView (вместо UIDatePicker).Что не сразу очевидно (для меня, по крайней мере), так это то, как заставить его работать с клавиатурой в качестве вида ввода.

0 голосов
/ 21 июня 2011

Свойство inputView является только частью UITextField и UITextView, а не UIButton.

   @property (readwrite, retain) UIView *inputView;

Хотя вы можете добиться того же, используя UIButton.

Создайте объект UIButton, затем установите метод action и добавьте свое представление выбора в родительское представление вашей кнопки в методе действия UIButton.

Должно быть что-то подобное.

-(void) buttonClicked:(id) sender
{
    [self.view addSubview:myPickerView];
}
...