Создавайте календарь программно в режиме быстрого доступа / доступа со встроенным календарем iOS - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь создать собственный календарь в своем приложении и нашел учебник по созданию собственного календаря (https://github.com/patchthecode/JTAppleCalendar), которому я следовал в новом проекте, и он работал. Однако в этом учебнике используются раскадровка и мой приложение не работает. Поэтому я попытался перенести настройку пользовательского интерфейса раскадровки в код с использованием подпредставлений, но безуспешно.

Цель этой функции - хранить деловые встречи в календаре, и я готов отказаться от пользовательской функции календаря и получить доступ к календарю iOS, но я не уверен, как это сделать.

Ошибка, которую я получаю при попытке запустить это Поток 1: Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения в view.addSubview (calendarView)

Приложение использует TabBarController для навигации, органайзер - одна из моих вкладок.

Буду очень признателен за любую помощь в создании собственного календаря или кода, который я смогу использовать для доступа к календарю iOS.

код ниже.

import UIKit
import JTAppleCalendar
import EventKit
class Organiser: UIViewController {

var calendarView: JTAppleCalendarView!
var year: UILabel!
var month: UILabel!

let outsideMonthColour = UIColor.white
let monthColour = UIColor.black
let selectedMonthColour = UIColor.red
let currentDateSelectedColour = UIColor.blue


let formatter = DateFormatter()

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(calendarView)
    view.addSubview(year)
    view.addSubview(month)


    calendarView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive=true
    calendarView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive=true
    calendarView.heightAnchor.constraint(equalToConstant: 200)
    calendarView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: -30)

    month.bottomAnchor.constraint(equalTo: calendarView.topAnchor, constant: 25)
    month.leftAnchor.constraint(equalTo: calendarView.leftAnchor, constant: 0)


    year.bottomAnchor.constraint(equalTo: month.topAnchor, constant: 25)
    year.leftAnchor.constraint(equalTo: month.leftAnchor, constant: 25)

    calendarView.translatesAutoresizingMaskIntoConstraints = false
    month.translatesAutoresizingMaskIntoConstraints = false
    year.translatesAutoresizingMaskIntoConstraints = false

    // Do any additional setup after loading the view, typically from a nib.
}


//setup calendar cells
func setupCalendarView(){
    calendarView.minimumLineSpacing = 0
    calendarView.minimumInteritemSpacing = 0

    calendarView.visibleDates { visibleDates in
        self.setupViewsOfCalendar(from: visibleDates)
    }
}

//setup selected cell text colour function
func handleCellTextColour(view: JTAppleCell?, cellState: CellState){
    guard let validCell = view as? CustomCell else { return }

    if cellState.isSelected {
        validCell.dateLabel?.textColor = currentDateSelectedColour
    } else {
        if cellState.dateBelongsTo == .thisMonth {
            validCell.dateLabel?.textColor = monthColour
        } else {
            validCell.dateLabel?.textColor = outsideMonthColour
        }
    }

}

//setup selected cell highlight function
func handleCellSelected(view: JTAppleCell?, cellState: CellState){
    guard let validCell = view as? CustomCell else { return }

    if cellState.isSelected {
        validCell.selectedView?.isHidden = false
    } else {
        validCell.selectedView?.isHidden = true
    }
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}


extension Organiser: JTAppleCalendarViewDataSource{
func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
    formatter.dateFormat = "yyyy mm dd"
    formatter.timeZone = Calendar.current.timeZone
    formatter.locale = Calendar.current.locale

    let startDate = formatter.date(from: "2017 01 01")
    let endDate = formatter.date(from: "2018 12 31")

    let parameters = ConfigurationParameters(startDate: startDate!, endDate: endDate!)
    return parameters
}

}


extension Organiser: JTAppleCalendarViewDelegate{

func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
    let myCustomCell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
    myCustomCell.dateLabel?.text = cellState.text

    handleCellSelected(view: cell, cellState: cellState)
    handleCellTextColour(view: cell, cellState: cellState)
    return ()
}

func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
    let myCustomCell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
    self.calendar(calendar, willDisplay: myCustomCell, forItemAt: date, cellState: cellState, indexPath: indexPath)
    myCustomCell.dateLabel?.text = cellState.text
    return myCustomCell
}
//function for handling interface changes when cell selected
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    handleCellSelected(view: cell, cellState: cellState)
    handleCellTextColour(view: cell, cellState: cellState)
}
//function for handling interface changes when cell deselected selected
func calendar(_ calendar: JTAppleCalendarView, didDeselectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    handleCellSelected(view: cell, cellState: cellState)
    handleCellTextColour(view: cell, cellState: cellState)
}
//function so that month and year show when calendar loads
func setupViewsOfCalendar(from visibleDates: DateSegmentInfo){
    let date = visibleDates.monthDates.first!.date

    self.formatter.dateFormat = "yyyy"
    self.year.text = self.formatter.string(from: date)

    self.formatter.dateFormat = "MMMM"
    self.month.text = self.formatter.string(from: date)
}

//function to change month when calendar scrolled
func calendar(_ calendar: JTAppleCalendarView, didScrollToDateSegmentWith visibleDates: DateSegmentInfo) {
    let date = visibleDates.monthDates.first!.date

    formatter.dateFormat = "yyyy"
    year.text = formatter.string(from: date)

    formatter.dateFormat = "MMMM"
    month.text = formatter.string(from: date)
}

}

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Вы принудительно распаковываете экземпляр JTAppleCalendar с помощью "!". Таким образом, при принудительном развертывании, если значение равно nil, приложение будет зависать. Чтобы избежать того же самого, вам нужно выполнить следующие шаги.

Шаг 1 : Вы можете добавить UIView из библиотеки объектов в xib или раскадровку.

Шаг 2 : Затем вам нужно установить JTAppleCalenderView в Identity Inspector, как показано на рисунке ниже. enter image description here

Тогда вы можете использовать тот же код, который вы использовали, и он не должен падать.

Примечание: Вам необходимо добавить то же самое с UILabel, чтобы избежать сбоя UILabel.

0 голосов
/ 01 сентября 2018

Сбой, который вы получаете, заключается в том, что вы не инициализируете JTAppleCalendarView, поэтому, когда вы пытаетесь добавить его в качестве подпредставления, он равен нулю. Компилятор не жалуется, потому что вы принудительно разворачиваете его в объявлении.

Заменить

var calendarView: JTAppleCalendarView!

С

let calendarView = JTAppleCalendarView()

Обратите внимание, что по тем же причинам вы получите сбои в следующих двух строках, когда вы попытаетесь добавить метки года и месяца в качестве подпредставлений.

Вы можете заменить их объявления на:

let year = UILabel()
let month = UILabel()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...