質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.46%

  • Swift

    4879questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    2881questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Xcode

    2766questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift3でのカレンダー実装について

解決済

回答 1

投稿 2017/01/14 14:12

  • 評価
  • クリップ 1
  • VIEW 1,490
退会済みユーザー

退会済みユーザー

前提・実現したいこと

iOSにてカレンダーのアプリを作るため、以下の記事を参考に製作しています。
http://qiita.com/sakuran/items/3c2c9f22cbcbf4aff731

発生している問題・エラーメッセージ

現在swift3で作っていますが、記事がswift3以前のモノだったのでエラーが発生し、解決できていない状況です。

該当のソースコード

ソース途中のコメント部がエラーメッセージです

ViewController.siwft
    //headerの月を変更
    func changeHeaderTitle(date: NSDate) -> String {
        let formatter: DateFormatter = DateFormatter()
        formatter.dateFormat = "M/yyyy"
        let selectMonth = formatter.string(from: date as Date) //Cannot convert value of type 'NSDate' to type 'Date' in coercion 'エラー1'
        return selectMonth
    }

    //①タップ時
    @IBAction func tappedHeaderPrevBtn(sender: UIButton) {
        selectedDate = dateManager.prevMonth(selectedDate)
        calenderCollectionView.reloadData() //Value of type 'DataManager' has no member 'prevMonth' 'エラー2'
        headerTitle.text = changeHeaderTitle(date: selectedDate)
    }

    //②タップ時
    @IBAction func tappedHeaderNextBtn(sender: UIButton) {
        selectedDate = dateManager.nextMonth(selectedDate)
        calenderCollectionView.reloadData() //Value of type 'DataManager' has no member 'nextMonth' 'エラー3'
        headerTitle.text = changeHeaderTitle(date: selectedDate)
    }

    //セルのサイズを設定
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let numberOfMargin: CGFloat = 8.0
        let width: CGFloat = (collectionView.frame.size.width - cellMargin * numberOfMargin) / CGFloat(daysPerWeek)
        let height: CGFloat = width * 1.0
        return CGSizeMake(width, height) // 'CGSizeMake' is unavailable in Swift 'エラー4'
DateManager.siwft
import UIKit

extension NSDate {
    func monthAgoDate() -> NSDate {
        let addValue = -1
        let calendar = NSCalendar.current
        let dateComponents = NSDateComponents()
        dateComponents.month = addValue
        return calendar.dateByAddingComponents(dateComponents, toDate: self, options: NSCalendar.Options(rawValue: 0))! // Value of type 'Calendar' has no member 'dateByAddingComponents' ’エラー5’
    }

    func monthLaterDate() -> NSDate {
        let addValue: Int = 1
        let calendar = NSCalendar.current
        let dateComponents = NSDateComponents()
        dateComponents.month = addValue
        return calendar.dateByAddingComponents(dateComponents, toDate: self, options: NSCalendar.Options(rawValue: 0))!// Value of type 'Calendar' has no member 'dateByAddingComponents' ’エラー6’
    }

}

class Date: NSObject {
    //省略

    //前月の表示
    func prevMonth(date: NSDate) -> NSDate {
        let currentMonthOfDates = [] // Empty collection literal requires an explicit type ’エラー7’
        selectedDate = date.monthAgoDate() //User of unresolved identifier 'selectedDate' ’エラー8’
        return selectedDate //User of unresolved identifier 'selectedDate' ’エラー9’
    }
    //次月の表示
    func nextMonth(date: NSDate) -> NSDate {
        currentMonthOfDates = [] //User of unresolved identifier 'currentMonthOfDates' ’エラー10’
        selectedDate = date.monthLaterDate() //User of unresolved identifier 'selectedDate' ’エラー11’
        return selectedDate //User of unresolved identifier 'selectedDate' ’エラー12’
    }
}


class DateManager: NSObject {
    var currentMonthOfDates = [NSDate]() //表記する月の配列
    var selectedDate = NSDate()
    let daysPerWeek: Int = 7
    var numberOfItems: Int!

    //月ごとのセルの数を返すメソッド
    func daysAcquisition() -> Int {
        let rangeOfWeeks = NSCalendar.current.range(of: NSCalendar.Unit.weekOfMonth, in: NSCalendar.Unit.month, for: firstDateOfMonth() as Date) //Cannot convert value of type 'NSCalendar.Unit' to expected argument type 'Calendar.Component' ’エラー13’
        let numberOfWeeks = rangeOfWeeks.length //月が持つ週の数
        numberOfItems = numberOfWeeks * daysPerWeek //週の数×列の数
        return numberOfItems
    }
    //月の初日を取得
    func firstDateOfMonth() -> NSDate {
        let components = NSCalendar.currentCalendar.components([.Year, .Month, .Day], //Type of expression is ambiguous without more context ’エラー14’
                                                                 fromDate: selectedDate)
        components.day = 1
        let firstDateMonth = NSCalendar.currentCalendar().dateFromComponents(components)!
        return firstDateMonth
    }

    // ⑴表記する日にちの取得
    func dateForCellAtIndexPath(numberOfItems: Int) {
        // ①「月の初日が週の何日目か」を計算する
        let ordinalityOfFirstDay = NSCalendar.currentCalendar.ordinalityOfUnit(NSCalendar.Unit.Day, inUnit: NSCalendar.Unit.WeekOfMonth, forDate: firstDateOfMonth()) // Value of type 'Calendar' has no member 'ordinalityOfUnit' ’エラー15’
        for i in 0 ..< numberOfItems {
            // ②「月の初日」と「indexPath.item番目のセルに表示する日」の差を計算する
            let dateComponents = NSDateComponents()
            dateComponents.day = i - (ordinalityOfFirstDay - 1)
            // ③ 表示する月の初日から②で計算した差を引いた日付を取得
            let date = NSCalendar.currentCalendar.dateByAddingComponents(dateComponents, toDate: firstDateOfMonth(), options: NSCalendar.Options(rawValue: 0))! //Value of type 'Calendar' has no member 'dateByAddingComponents' ’エラー16’
            // ④配列に追加
            currentMonthOfDates.append(date)
        }
    }

    // ⑵表記の変更
    func conversionDateFormat(indexPath: NSIndexPath) -> String {
        dateForCellAtIndexPath(numberOfItems: numberOfItems)
        let formatter: DateFormatter = DateFormatter()
        formatter.dateFormat = "d"
        return formatter.string(from: currentMonthOfDates[indexPath.row] as Date) // Cannot convert value of type 'NSDate' to type 'Date' in coercion ’エラー17’
    }
}

試したこと

色々調べて試しましたが解決できないため質問させていただきました。
よろしくお願いいたします。

補足情報(言語/FW/ツール等のバージョンなど)

足りない情報等あれば追記致します。
エラーが多いですが、よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2017/01/16 15:04

    こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

+3

私も同じカレンダーを参考にしてSwift3用にエラー修正をしていますが私の場合はエラーは修正して起動して落ちなくなりました、ご質問のエラー箇所の解説をいたします、参考にしてください
早速ですが、私の意見で解説しますが、それを参考にしてもう少し努力してください、必ず解決しますよ
解決するまで諦めないでください、もしも、どうしても解決しない場合は私のFacebookにメッセージしてください
Xcode 8.2.1
Swift 3.0
macOS Sierra

ViewController.siwft

//headerの月を変更
    // 🔴修正前 (date: NSDate)
    func changeHeaderTitle() -> String {
        let formatter: DateFormatter = DateFormatter()
        //let formatter = DateFormatter() // 🔴これでもOKです
        formatter.dateFormat = "M/yyyy"
        // 🔴修正前 formatter.string(from: date as Date)
        let selectMonth = formatter.string(from: selectedDate)
        return selectMonth
    }

    //①タップ時
    // 🔴修正前 (sender: UIButton)
    @IBAction func tappedHeaderPrevBtn(_ sender: UIButton) {
        // 🔴修正前 (selectedDate)
        selectedDate = dateManager.prevMonth(date: selectedDate)
        calenderCollectionView.reloadData()
        // 🔴修正前 (date: selectedDate)
        headerTitle.text = changeHeaderTitle()
}
    //②タップ時
    // 🔴修正前 (sender: UIButton)
    @IBAction func tappedHeaderNextBtn(_ sender: UIButton) {
        // 🔴修正前 (selectedDate)
        selectedDate = dateManager.nextMonth(date: selectedDate)
        calenderCollectionView.reloadData()
        // 🔴修正前 (date: selectedDate)
        headerTitle.text = changeHeaderTitle()
    }

//セルのサイズを設定
    // 🔴修正前 (collectionView:
    // 🔴修正前 sizeForItemAtIndexPath indexPath: NSIndexPath)
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let numberOfMargin: CGFloat = 8.0
        let width: CGFloat = (collectionView.frame.size.width - cellMargin * numberOfMargin) / CGFloat(daysPerWeek)
        let height: CGFloat = width * 1.0
        // 🔴修正前 CGSizeMake(width, height)
        return CGSize(width: width, height: height)
    }

コード
DateManager.siwft

import UIKit

extension Date {
        // 🔴修正前 -> NSDate
    func monthAgoDate() -> Date {
        let addValue = -1
        // 🔴修正前 = NSCalendar.currentCalendar()
        let calendar = Calendar.current
        // 🔴修正前 let dateComponents = DateComponents()
        var dateComponents = DateComponents()
        dateComponents.month = addValue
        // 🔴修正前 return calendar.dateByAddingComponents(dateComponents, toDate: self, options: NSCalendarOptions(rawValue: 0))!
        return calendar.date(byAdding: dateComponents, to: self)!
    }
        // 🔴修正前 -> NSDate
    func monthLaterDate() -> Date {
        let addValue: Int = 1
        // 🔴修正前 = NSCalendar.currentCalendar()
        let calendar = Calendar.current
        // 🔴修正前 let dateComponents = DateComponents()
        var dateComponents = DateComponents()
        dateComponents.month = addValue

        // 🔴修正前 return calendar.dateByAddingComponents(dateComponents, toDate: self, options: NSCalendarOptions(rawValue: 0))!
        return calendar.date(byAdding: dateComponents, to: self)!
    }
}

class DateManager: NSObject {

    var currentMonthOfDates = [NSDate]() //表記する月の配列
    // 🔴修正前 NSDate()
    var selectedDate = Date()
    let daysPerWeek: Int = 7
    // 🔴修正前 Int!
    var numberOfItems: Int! = 0 //セルの個数 nilが入らないようにする

    //月ごとのセルの数を返すメソッド
    func daysAcquisition() -> Int {
        // 🔴修正前 NSCalendar.currentCalendar().rangeOfUnit(NSCalendarUnit.WeekOfMonth, inUnit: NSCalendarUnit.Month, forDate: firstDateOfMonth())
        let rangeOfWeeks = Calendar.current.range(of: .weekOfMonth, in: .month, for: firstDateOfMonth() as Date)

        // 🔴修正前 rangeOfWeeks.length
        let numberOfWeeks = Int((rangeOfWeeks?.count)!) //月が持つ週の数
        numberOfItems = numberOfWeeks * daysPerWeek //週の数×列の数
        return numberOfItems
    }
    //月の初日を取得
    func firstDateOfMonth() -> Date {
        // 🔴修正前 let components = NSCalendar.currentCalendar().components([.Year, .Month, .Day], fromDate: selectedDate)
        var components = Calendar.current.dateComponents([.year, .month, .day], from:selectedDate)
        components.day = 1
        // 🔴修正前 NSCalendar.currentCalendar().dateFromComponents(components)!
        let firstDateMonth = Calendar.current.date(from: components)!
        return firstDateMonth
    }

    // ⑴表記する日にちの取得
    func dateForCellAtIndexPath(numberOfItem: Int) {
        // ①「月の初日が週の何日目か」を計算する
        // 🔴修正前 NSCalendar.currentCalendar().ordinalityOfUnit(NSCalendarUnit.Day, inUnit: NSCalendarUnit.WeekOfMonth, forDate: firstDateOfMonth())
        let ordinalityOfFirstDay = Calendar.current.ordinality(of: .day, in: .weekOfMonth, for: firstDateOfMonth())
        // 🔴修正前 for var i = 0; i < numberOfItems; i++ {
        for i in 0 ..< numberOfItems {
            // ②「月の初日」と「indexPath.item番目のセルに表示する日」の差を計算する
            var dateComponents = DateComponents()
            // 🔴修正前 (ordinalityOfFirstDay - 1)
            dateComponents.day = i - (ordinalityOfFirstDay! - 1)
            // ③ 表示する月の初日から②で計算した差を引いた日付を取得
            // 🔴修正前 NSCalendar.currentCalendar().dateByAddingComponents(dateComponents, toDate: firstDateOfMonth(), options: NSCalendarOptions(rawValue: 0))!
            let date = Calendar.current.date(byAdding: dateComponents as DateComponents, to: firstDateOfMonth() as Date)!
            // ④配列に追加
            // 🔴修正前 (date)
            currentMonthOfDates.append(date as NSDate)
        }
    }

    // ⑵表記の変更
    // 🔴修正前 (indexPath: NSIndexPath)
    func conversionDateFormat(indexPath: IndexPath) -> String {
        // 🔴修正前 (numberOfItems)
        dateForCellAtIndexPath(numberOfItem: numberOfItems)
        // 🔴修正前 NSDateFormatter = NSDateFormatter()
        let formatter: DateFormatter = DateFormatter()
        formatter.dateFormat = "d"
        // 🔴修正前 return formatter.stringFromDate(currentMonthOfDates[indexPath.row])
        return formatter.string(from: currentMonthOfDates[indexPath.row] as Date)
    }

    //前月の表示
    // 🔴修正前 (date: NSDate) -> NSDate
    func prevMonth(date: Date) -> Date {
        currentMonthOfDates = []
        selectedDate = date.monthAgoDate()
        return selectedDate
    }

    //次月の表示
    // 🔴修正前 (date: NSDate) -> NSDate
    func nextMonth(date: Date) -> Date {
        currentMonthOfDates = []
        selectedDate = date.monthLaterDate()
        return selectedDate
    }
}

コード

投稿 2017/01/15 10:22

編集 2017/01/18 14:31

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/17 10:58 編集

    コードは ``` で囲うと見やすくなりますよ。

    ```swift
    コード
    ```

    参考:https://teratail.com/help

    キャンセル

  • 2017/01/17 16:02

    知りませんでした、ご指摘ありがとうございました、感謝いたします

    キャンセル

  • 2017/01/19 01:16

    記載していただいた通りで解決できました!ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.46%

関連した質問

同じタグがついた質問を見る

  • Swift

    4879questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    2881questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Xcode

    2766questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。