Откройте UIDatePicker программно в iOS 14

У меня есть это обычное UIDatePicker (извините, что это не на английском языке, пожалуйста, не обращайте на это внимания):

мой выбор даты

Но проблема в том, что он появляется только тогда, когда я нажимаю средство выбора даты:

изображение

И я хотел знать, как показать средство выбора даты, как на первом изображении (что оно покрывает весь экран с эффектом размытия) только с помощью кода, чтобы пользователю не нужно было нажимать кнопку даты Picker для отображения селектора даты. Спасибо.


person אורי orihpt    schedule 09.08.2020    source источник
comment
Как вы создали этот интерфейс? раскадровка? код? у тебя есть розетка?   -  person zaitsman    schedule 10.08.2020
comment
Раскадровка, и да, у меня есть выход. Но меню с первого изображения генерируется, когда я нажимаю компактное меню   -  person אורי orihpt    schedule 10.08.2020
comment
Вы нашли решение?   -  person Ruben Nahatakyan    schedule 23.09.2020
comment
нет, не сейчас . .   -  person אורי orihpt    schedule 24.09.2020
comment
Вы можете заставить объект стать первым ответившим с помощью yourPicker.becomeFirstResponder(). Это должно более или менее имитировать нажатие на поле даты.   -  person Sanzio Angeli    schedule 04.10.2020
comment
@SanzioAngeli, это не работает   -  person אורי orihpt    schedule 04.10.2020
comment
Подкласс UITextView и DateFormatter, чтобы отобразить дату в желаемом формате, сделать ее редактируемой, установить средство выбора даты как inputView текстового представления, а затем yourtextView.becomeFirstResponder(). Это работает, у меня это реализовано.   -  person Sanzio Angeli    schedule 05.10.2020
comment
@SanzioAngeli Пожалуйста, отправьте это как ответ и предоставьте более подробную информацию   -  person אורי orihpt    schedule 07.10.2020
comment
После дальнейшего тестирования, чтобы попытаться дать ответ, вы правы, это не работает. Это работает только для стиля .wheels (именно так я стилизовал свой). Извините за путаницу.   -  person Sanzio Angeli    schedule 07.10.2020
comment
Посмотрите на решение ниже, используя GraphicalDatePickerStyle из SwiftUI.   -  person lorem ipsum    schedule 21.12.2020
comment
Хороший вопрос. Я еще не нашел ответ. Но я нашел, как закрыть полноэкранный контроллер календаря. После выбора даты мы можем скрыть ее (_UIDatePickerIOSCompactViewController) с помощью простого dismiss() (найти верхнюю vc)   -  person SoftDesigner    schedule 07.01.2021
comment
@SoftDesigner Я хочу попробовать то, что вы предложили, но не могу найти, как это сделать. Пожалуйста, поделитесь еще кодом?   -  person אורי orihpt    schedule 07.01.2021
comment
@אוריorihpt, проверьте код здесь: gist.github.com/vvit/22b33b779ba85db85e02bc5bcc5979a0   -  person SoftDesigner    schedule 07.01.2021


Ответы (12)


У меня та же проблема. Я использую следующий хак:

let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
datePicker.preferredDatePickerStyle = .compact

// Removes Labels
datePicker.subviews.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })

Затем я просто добавляю это средство выбора даты поверх представления, которое должно открыть это всплывающее окно.

person A. Berisha    schedule 27.09.2020
comment
Спасибо за предложение, но я не буду отмечать его как принятое, потому что оно не отвечает на все мои вопросы. Пользователю по-прежнему нужно нажать на средство выбора даты, чтобы оно открылось. Я хотел решение, что вместо того, чтобы пользователь нажимал, я буду делать это только с помощью кода. - person אורי orihpt; 27.09.2020
comment
Я думаю, что это самое близкое, что можно получить для достижения этой функциональности. - person Shunan; 08.11.2020
comment
Не работает для меня. - person Dmitry; 09.05.2021

Невозможно открыть UIDatePicker с помощью UIKit14 из кода

  • UIDatePicker не имеет API для этого
  • UIKit не позволяет нам создавать объекты UIEvents или UITouch, которые каким-либо образом влияют на UIKit.
person Blazej SLEBODA    schedule 03.10.2020
comment
Я знаю это, я ищу обходной путь, который даст тот же результат, что и нажатие на средство выбора даты. - person אורי orihpt; 04.10.2020
comment
@TLGCodin' Это невозможно - person Blazej SLEBODA; 04.10.2020
comment
я так не думаю - person אורי orihpt; 04.10.2020
comment
Я создал награду и буду рад, если кто-то покажет мне, что я ошибался - person Blazej SLEBODA; 04.10.2020
comment
У меня есть вопрос, который может помочь вам с этим, что вызовет появление средства выбора даты? Я знаю, вы сказали, что хотите программно, но за этим должно быть действие. Будет ли пользователь на что-нибудь нажимать? Будет ли приложение открывать его в какой-то определенный момент или поведение? - person J Arango; 30.11.2020
comment
@JArango Триггер в моем конкретном коде нажимает кнопку UIButton. Но я спросил вообще как это сделать с кодом, неважно какой триггер - person אורי orihpt; 03.12.2020
comment
Я могу сказать, что ты не можешь что-то сделать, но никогда нельзя сказать, что это невозможно. Все возможно в этом мире. - person Dmitry; 09.05.2021

Вы можете использовать datePicker со стилем .compact и поместить UILabel поверх него и присвоить ему цвет фона, чтобы скрыть datePicker за ним, и убедиться, что взаимодействие с пользователем метки отключено, тогда вы сможете нажать на datePicker, и он покажет модальное, а затем значение, измененное для datePicker, вы можете использовать свой собственный форматировщик даты, чтобы соответствующим образом установить текст метки, вы также можете использовать как datePicker, так и метку внутри UIView и сделать его обрезанным до границ

person Amr Mohamed    schedule 23.12.2020
comment
Это умный обходной путь. Это сработало для меня. У меня было два выбора даты рядом. Просто нужно было убедиться, что они выстроены правильно, чтобы клики от (меньших) меток проходили. - person Dylan; 17.01.2021

К сожалению, невозможно программно отобразить всплывающее окно выбора даты, по крайней мере, не прибегая к хакам, которые могут привести к отклонению вашего приложения:

  • элемент управления UIDatePicker не предоставляет никаких событий, которые могут быть программно запущены с помощью sendActions(for:) - allControlEvents возвращает пустой набор параметров

  • программная имитация щелчка пользователя официально невозможна на iOS - для этого нет общедоступного API, все обходные пути подразумевают обращение к частным API

  • если вышеперечисленного недостаточно, структура пользовательского интерфейса UIDatePicker состоит из частных классов:

    «введите введите здесь описание изображения

Вывод состоит в том, что в текущем состоянии пользовательским интерфейсом UIDatePicker можно управлять только посредством взаимодействия с пользователем. Возможно, это изменится в будущем, например, UIButton выставит действия для запуска того же поведения, что и когда пользователь нажал кнопку, поэтому, возможно, UIDatePicker выставит такие действия в будущем.

person Cristik    schedule 08.10.2020
comment
Никто не отклоняет приложения, если они не падают. - person Dmitry; 09.05.2021
comment
@Dmitry, использующий частный (iOS SDK) API, гарантированно приведет к тому, что ваш двоичный файл будет автоматически отклонен инструментами, которые запускаются после отправки сборки в AppStore. - person Cristik; 23.05.2021
comment
Никогда не видел, чтобы это произошло, когда это было так. - person Dmitry; 24.05.2021

Я не знаю, актуально ли это, но вы можете использовать стиль .inline нового UIDatePicker. Затем используйте собственное представление и анимацию, чтобы имитировать внешний вид DatePicker из стиля .compact.

        let secondDatePicker = UIDatePicker()
        secondDatePicker.preferredDatePickerStyle = .inline
        self.view.addSubview(secondDatePicker)
        
        secondDatePicker.translatesAutoresizingMaskIntoConstraints = false
        secondDatePicker.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        secondDatePicker.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
person Praveen Kumar B    schedule 29.10.2020
comment
Это довольно умно, если вы можете хорошо определить размер всплывающего окна. - person spentag; 27.01.2021

Ответ @Amr Mohamed умный, поместив метку в представление выбора даты, но это также вызывает сбой при нажатии на представление выбора даты, когда vc выбора даты анимируется, вы также можете увидеть средство выбора даты.

Поэтому нам нужно скрыть вид выбора даты, но при этом оставить его интерактивным. (Мы не можем просто использовать isHidden = true или alpha = 0, иначе его больше нельзя будет нажать)

Вот как я сделал в своем проекте:

extension UIView {
    func loopDescendantViews(_ closure: (_ subView: UIView) -> Void) {
        for v in subviews {
            closure(v)
            v.loopDescendantViews(closure)
        }
    }
}

let datePicker = UIDatePicker()
datePicker.preferredDatePickerStyle = .compact
datePicker.loopDescendantViews {
    $0.alpha = $0 is UIControl ? 1 : 0
}

Затем вы можете поместить это невидимое средство выбора даты поверх ярлыка/другого представления. как только вы коснетесь метки (на самом деле коснулись средства выбора даты), средство выбора даты vc анимируется.

person iAugus    schedule 10.03.2021
comment
Довольно умно! Это сработало для меня ???? - person Roger Oba; 12.03.2021
comment
Это здорово. Спасибо! - person nil; 24.06.2021

Я думаю, что единственный не хакерский подход — создать новый контроллер представления, добавить в него экземпляр UIDatePicker со встроенным стилем, а затем представить контроллер модально или в виде всплывающего окна.

person gklka    schedule 04.02.2021
comment
дубликат? stackoverflow.com/a/63333081/14016301 - person אורי orihpt; 05.02.2021

Он работает, чтобы переключиться на старый стиль выбора даты:

        if (@available(iOS 13.4, *)) {
            [datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
        }
person Dmitry    schedule 09.05.2021
comment
Иногда правильный ответ лежит за рамками исходного вопроса. - person Dmitry; 12.05.2021
comment
Этот ответ не является вашей собственностью stackoverflow.com/a/64710218/14016301 - person אורי orihpt; 13.05.2021

Определите эти переменные

var datePicker: UIDatePicker!
var datePickerConstraints = [NSLayoutConstraint]()
var blurEffectView: UIView!

Затем создайте функцию showDatePicker(), которую вы вызываете для запуска отображения UIDatePicker. Во-первых, создайте подвид того же размера, что и его родительский вид, и придайте ему эффект размытия. Затем добавьте UIDatePicker в качестве подвида поверх размытого вида.

   func showDatePicker() {
        datePicker = UIDatePicker()
        datePicker?.date = Date()
        datePicker?.locale = .current
        datePicker?.preferredDatePickerStyle = .inline
        datePicker?.addTarget(self, action: #selector(dateSet), for: .valueChanged)
        addDatePickerToSubview()
    }

    func addDatePickerToSubview() {
        guard let datePicker = datePicker else { return }
        // Give the background Blur Effect
        let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.regular)
        blurEffectView = UIVisualEffectView(effect: blurEffect)
        blurEffectView.frame = self.view.bounds
        blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.view.addSubview(blurEffectView)
        self.view.addSubview(datePicker)
        datePicker.translatesAutoresizingMaskIntoConstraints = false
        centerDatePicker()
        view.bringSubviewToFront(datePicker)
    }

    func centerDatePicker() {
        guard let datePicker = datePicker else { return }
        // Center the Date Picker
        datePickerConstraints.append(datePicker.centerYAnchor.constraint(equalTo: self.view.centerYAnchor))
        datePickerConstraints.append(datePicker.centerXAnchor.constraint(equalTo: self.view.centerXAnchor))
        NSLayoutConstraint.activate(datePickerConstraints)
    }

И, наконец, однажды выбранная дата в UIDatePicker

 @objc func dateSet() {
        // Get the date from the Date Picker and put it in a Text Field
        compactDatePicker.date = datePicker.date
        blurEffectView.removeFromSuperview()
        datePicker.removeFromSuperview()
    }

Не совсем уверен в эффекте размытия, поэтому, надеюсь, кто-то сможет использовать это решение.

person Sami    schedule 04.10.2020
comment
Но dateTextField нет. Существует компактный выбор даты, и идея состоит в том, чтобы открыть его, как если бы пользователь коснулся его. - person matt; 04.10.2020
comment
я не знаю ни одного метода, чтобы подделать пользователя, нажимающего на компактное средство выбора даты, поэтому я подумал, что с приведенным выше кодом я подделаю его, представив другое средство выбора даты во встроенном стиле, а затем при отклонении установите значение исходного компактного средства выбора даты на только что представленного. - person Sami; 04.10.2020

Если вы хотите продолжить использовать формат колес, вы можете установить стиль колес на доске раскадровки,

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

или используйте этот код

datePicker.preferredDatePickerStyle = .wheels
person Mona    schedule 06.11.2020
comment
Нет. Прочитайте мой вопрос еще раз. - person אורי orihpt; 06.11.2020
comment
Это касается не только вашего конкретного вопроса. иногда эта страница появлялась у меня, когда я искал способ продолжить использование колес, и она будет отображаться в Google для других, которые будут искать то же самое в будущем. Я разместил этот ответ, чтобы помочь этим людям. в своем ответе я также упомянул, что это решение для людей, которые хотят продолжать использовать колеса. - person Mona; 14.11.2020
comment
Спасибо, Мона!, я искал это. - person Joule87; 05.04.2021

Я предполагаю, что вы используете стиль выбора даты compact, который является новой функцией iOS 14. И я думаю, что вы можете просто использовать стиль ‏‏‏ inline вместо compact, чтобы отобразить полный интерфейс календаря. И не забывайте, что UIDatePicker — это всего лишь UIView, так что вы можете настроить свою презентацию, чтобы реализовать желаемый эффект размытия.

person congnd    schedule 10.08.2020
comment
Да, я знаю это. Но нет способа открыть компактное средство выбора даты с помощью кода, а затем, когда пользователь закрывает его, оно снова становится маленьким? - person אורי orihpt; 10.08.2020
comment
Какое действие будет триггером для представления полноэкранного пользовательского интерфейса средства выбора? - person congnd; 10.08.2020
comment
Нажатие элемента в UIMenu - person אורי orihpt; 11.08.2020
comment
Вы можете использовать пользовательский интерфейс в стиле inline для программного представления полноэкранного средства выбора и настраиваемое представление для отображения выбранной даты. - person congnd; 11.08.2020
comment
а как же анимации? - person אורי orihpt; 11.08.2020
comment
Сделай сам тоже. Я рекомендую использовать UIPresentationController для настройки анимации перехода. - person congnd; 11.08.2020

Попробуй это -

datePicker.preferredDatePickerStyle = .inline
person ManjunathK    schedule 09.11.2020
comment
Это даже близко не то, что я просил - person אורי orihpt; 09.11.2020