简体   繁体   中英

Swift : UITableView Passing Calendar Event Data to DetailViewController

I have a tableview, which loads the calendar events into rows dynamically. I'am checking for device's current day events. I set a detailview because I will pass that event data to the detailview labels. I am using storyboard segues. But I could not complete it yet. Can anyone help me what I am missing?

The error is "Cannot assign value of type 'EKEvent?' to type 'String?'" Should I convert the EKEvent Date type to the string? or How, I need an example for that. I am practicing my swift skills.

Here is my code below;

class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var needPermissionView: UIView!
@IBOutlet weak var calendarsTableView: UITableView!
@IBOutlet weak var dateLabel: UILabel!

var event : [EKEvent]?
var calendars: [EKCalendar]?
let eventStore = EKEventStore()

override func viewDidLoad() {
    super.viewDidLoad()  
    loadEvents()

    calendarsTableView.delegate = self
    calendarsTableView.dataSource = self

    calendarsTableView.estimatedRowHeight = 44
    calendarsTableView.rowHeight = UITableViewAutomaticDimension

    calendarsTableView.reloadData()

}

    override func viewWillAppear(_ animated: Bool) {
    checkCalendarAuthorizationStatus()
}

    func checkCalendarAuthorizationStatus() {
    let status = EKEventStore.authorizationStatus(for: EKEntityType.event)

    switch (status) {
    case .notDetermined:
        requestAccessToCalendar()
    case .restricted, .denied:
        needPermissionView.fadeIn()
    case .authorized:
        loadCalendars()
        loadEvents()
        refreshTableView()
    }
}

func requestAccessToCalendar() {
    eventStore.requestAccess(to: .event) { (accessGranted, error) in
        if accessGranted == true {
            DispatchQueue.main.async {
                self.loadCalendars()
                self.loadEvents()
                self.refreshTableView()
            }
        } else {
            DispatchQueue.main.async {
                self.needPermissionView.fadeIn()
            }
        }
    }
}

func loadCalendars() {
    self.calendars = eventStore.calendars(for: EKEntityType.event)
}

func refreshTableView() {
    calendarsTableView.isHidden = false
    calendarsTableView.reloadData()
}

func loadEvents(){
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat =  "yyyy-MM-dd"

    let date = Date()
    let dateString = dateFormatter.string(from: date)

    print(dateString)
    dateLabel.text = dateString

    var components: DateComponents = DateComponents()
    components.setValue(1, for: .day)

    let expirationDate = Calendar.current.date(byAdding: components, to: date)
    //print(expirationDate ?? "expirationDate")

    let endString = dateFormatter.string(from: expirationDate!)

    // Create start and end date NSDate instances to build a predicate for which events to select
    let startDate = dateFormatter.date(from: dateString)
    let endDate = dateFormatter.date(from: endString)

    if let startDate = startDate, let endDate = endDate{
        let eventStore = EKEventStore()

        // Use an event store instance to create and properly configure an NSPredicate
        let eventsPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: calendars)

        // Use the configured NSPredicate to find and return events in the store that match
        self.event = eventStore.events(matching: eventsPredicate).sorted(by: { (e1, e2) -> Bool in
            return e1.startDate.compare(e2.startDate) == ComparisonResult.orderedAscending
        })
    }
}

@IBAction func goToSettingsButtonTapped(_ sender: UIButton) {
    let openSettingsUrl = URL(string: UIApplicationOpenSettingsURLString)
    UIApplication.shared.openURL(openSettingsUrl!)
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let events = self.event {
        return events.count
    }

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 90
    return 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    if let events = self.event {
        let eventName = events[(indexPath as NSIndexPath).row].title
        cell.textLabel?.text = eventName

        let eventDate = events[(indexPath as NSIndexPath).row].startDate
        let dateFormatter = DateFormatter()

        dateFormatter.dateFormat = "dd MMM yyyy  HH:mm"
        dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3")

        let timeStamp = dateFormatter.string(from: eventDate!)
        print(timeStamp)
        cell.detailTextLabel?.text = timeStamp
    } else {
        cell.textLabel?.text = "Unknown Calendar Name"
    }

    cell.textLabel?.numberOfLines = 0
    return cell
}

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail" {
        if let indexPath = calendarsTableView.indexPathForSelectedRow {
            let destVC = segue.destination as! DetailViewController
            destVC.taskNameLabel.text = event?[indexPath.row]
        }
    }
}

Your problem is here EKEvent var can't be assigned to text which is of type String

destVC.taskNameLabel.text = event?[indexPath.row]

you need to

destVC.sendedEvent = event?[indexPath.row]

//

class DetailViewController {
  var sendedEvent: EKEvent?
}

Then assign sendedEvent title or anything inside viewDidLoad of DetailViewController

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM