中年プログラマーの息抜き

ブログをはじめました。気の向くままにプログラム関連ネタをメモしていきます。

日当-ヒナタ- swift4 -6- DatePickerを使ってみる

はじめに

Androidアプリ日当-ヒナタ-のiOS版を作り始めたのでその経過を少しアップします。普段の仕事ではSWIFTを触らないのでとても新鮮な感じと少し不安なとこもあり。。。少し機能を削り、早めのストア公開を目指します。 picker系のコントロールが少し手こずります。AndroidではAdapterと紐づける感じですが、iOSでは手順が違うので、試しながら進めている感じです、、標準的と思われる方法で実装しているつもりですが、個人的な所感ですが、どうもフォーム部品というよりは、キーボードの代わり??という感じですね。

機材

Macbook air Xcode Version 10.1 Apple Swift version 4.2.1
・iphone5c テスト機

UIDatePickerを動かしてみました。

複数TableCellにダミーでTextFieldを配置して、TableCellラベルと連動させる方法です。ダミーTextFieldは1つで良いよ、とかプログラムから動的にとか、そもそもダミーTextFieldなんて要らないね、などいろいろ思いはありますが、今はこれで進めます。後々リファクタすると思いますがその時にしっかり実装すれば、、、今は動けば良いのです。。。

import UIKit
extension UITableViewCell {
    @IBInspectable
    var checked: Bool {
        get { return detailTextLabel?.text?.count ?? 0 > 0 }
        set(value) { detailTextLabel?.text = value ? "✔️" : "" }
    }
    var textView: UITextField {
        get {
            for v in self.contentView.subviews {
                if let text = v as? UITextField {
                    return text
                }
            }
            fatalError("implements none.")
        }
    }
}
class TripRegisterTableViewController: UITableViewController {
    
    @IBOutlet weak var mDateMin: UITableViewCell!
    @IBOutlet weak var mDateMax: UITableViewCell!
    @IBOutlet weak var mBackColor: UITextField!
    
    let datePickerView: UIDatePicker = UIDatePicker()
    
    static var dateFormat: DateFormatter = {
        let df: DateFormatter = DateFormatter()
        df.dateFormat = "yyyy年M月d日"
        return df
    }()
    
    func convert(_ text: String) -> Date {
        guard let result = TripRegisterTableViewController.dateFormat.date(from: text) else { return Date() }
        return result
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let toolbar = UIToolbar(frame: CGRect(x:0, y:0, width:0, height:35))
        toolbar.setItems([
            UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancel))
            , UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            , UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.done))], animated: true)
        datePickerView.datePickerMode = UIDatePicker.Mode.date
        datePickerView.timeZone = NSTimeZone.local
        datePickerView.locale = Locale.current
        mDateMin.textView.inputView = datePickerView
        mDateMin.textView.inputAccessoryView = toolbar
        mDateMax.textView.inputView = datePickerView
        mDateMax.textView.inputAccessoryView = toolbar
    }
    
    @objc func done() {
        switch datePickerView.tag {
        case 0:
            mDateMin.textView.endEditing(true)
            mDateMin.textView.text = TripRegisterTableViewController.dateFormat.string(from: datePickerView.date)
            mDateMin.detailTextLabel?.text = mDateMin.textView.text
            if ComparisonResult.orderedAscending == convert(mDateMax.textView.text!).compare(datePickerView.date) {
                mDateMax.textView.text = mDateMin.textView.text
                mDateMax.detailTextLabel?.text = mDateMin.textView.text
            }
            break
        case 1:
            mDateMax.textView.endEditing(true)
            mDateMax.textView.text = TripRegisterTableViewController.dateFormat.string(from: datePickerView.date)
            mDateMax.detailTextLabel?.text = mDateMax.textView.text
            if ComparisonResult.orderedDescending == convert(mDateMin.textView.text!).compare(datePickerView.date) {
                mDateMin.textView.text = mDateMax.textView.text
                mDateMin.detailTextLabel?.text = mDateMax.textView.text
            }
            break
        default:
            break
        }
    }
    
    @objc func cancel() {
        mDateMin.textView.endEditing(true)
        mDateMax.textView.endEditing(true)
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        switch indexPath.section {
        case 0:
            switch indexPath.row {
            case 0:
                datePickerView.tag = 0
                datePickerView.date = convert(mDateMin.detailTextLabel!.text!)
                mDateMin.textView.becomeFirstResponder()
            case 1:
                datePickerView.tag = 1
                datePickerView.date = convert(mDateMax.detailTextLabel!.text!)
                mDateMax.textView.becomeFirstResponder()
            case 2:
                tableView.cellForRow(at: indexPath)?.checked = !(tableView.cellForRow(at: indexPath)?.checked ?? true)
            default:
                break
            }
        default:
            break
        }
    }
}

class TripRegisterViewController: ViewController {
    
    var mTableView: TripRegisterTableViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.setRightBarButton(
            UIBarButtonItem(title: "保存", style: .plain, target: self, action: #selector(self.onClickSave)), animated: true)
        let today = TripRegisterTableViewController.dateFormat.string(from: Date())
        mTableView?.mDateMin.textView.text = today
        mTableView?.mDateMin.detailTextLabel?.text = today
        mTableView?.mDateMax.textView.text = today
        mTableView?.mDateMax.detailTextLabel?.text = today
    }
    
    @objc func onClickSave() {
        RealmHelper.shared.begin()
        RealmHelper.shared.commit()
        self.navigationController?.popViewController(animated: true)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)
        if let vc = segue.destination as? TripRegisterTableViewController {
            self.mTableView = vc
        }
    }

}

f:id:tm-b:20190129015949p:plain

f:id:tm-b:20190129015530p:plain

【Android】日当-ヒナタ-

月末に近づき、なかなか時間が取れなくなってきました。。

なんとかリリースまで・・がんばりたい

ab39

日当-ヒナタ- swift4 -5- Realmを使ってみる

はじめに

Androidアプリ日当-ヒナタ-のiOS版を作り始めたのでその経過を少しアップします。普段の仕事ではSWIFTを触らないのでとても新鮮な感じと少し不安なとこもあり。。。少し機能を削り、早めのストア公開を目指します。 RealmSwift、オブジェクトのクローズは不要??ひとまず参照を飛ばすだけにしました。

機材

Macbook air Xcode Version 10.1 Apple Swift version 4.2.1
・iphone5c テスト機

RealmHelperを変更して動くとこまで確認しました。

swiftでは必要ないか・・とも思ったのですが、Androidと同じ手順にしたいので設置(ラップしただけ・・ログを出したくなるかもしれませんし。。設計的にもありと思った。)

import RealmSwift

class RealmHelper {
    static let shared: RealmHelper = RealmHelper()
    private init() { }
    
    private let _lock = DispatchQueue(label: "RealmHelper")
    private var _realm: Realm?
    //プロパティでよいのだけど:Androidに合わせて()
    func realm()-> Realm {
        return _lock.sync {
            if _realm == nil { _realm = try!Realm() }
            return _realm!
        }
    }
    
    func begin() {
        _lock.sync {
            if _realm == nil { _realm = try!Realm() }
            _realm!.beginWrite()
        }
    }
    
    func rollback() {
        _lock.sync {
            if _realm == nil { return }
            if _realm!.isInWriteTransaction { _realm!.cancelWrite() }
            _realm = nil
        }
    }
    
    func commit() {
        _lock.sync {
            if _realm == nil { return }
            if _realm!.isInWriteTransaction { try?_realm!.commitWrite() }
            _realm = nil
        }
    }
    
    func close() {
        _lock.sync { _realm = nil }
    }
    
}

    

今日はおわり、つづきは明日。。

簡単なとこは少し動かしてOKでした。(動かないとこはおいおい直す)

ab39

Podfile(参考:#pod setup,#pod init,#pod install,#pod update)

# Uncomment the next line to define a global platform for your project
platform :ios, '10.3'

target 'btr' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  pod 'RealmSwift'
  #pod 'Google-Mobile-Ads-SDK'

end
    

日当-ヒナタ- swift4 -4- Realmを使ってみる

はじめに

Androidアプリ日当-ヒナタ-のiOS版を作り始めたのでその経過を少しアップします。普段の仕事ではSWIFTを触らないのでとても新鮮な感じと少し不安なとこもあり。。。少し機能を削り、早めのストア公開を目指します。 Realmオブジェクトは閉じ方がよくわかりません。 Androidとは扱い方が少し違いました。

機材

Macbook air Xcode Version 10.1 Apple Swift version 4.2.1
・iphone5c テスト機

とりあえずHelper作ります。

いらないかも、でも、Androidと同じインターフェイスを設置


import RealmSwift

class RealmHelper {
     static let shared: RealmHelper = RealmHelper()
     private init() {}
     var realm: Realm { get { return try!Realm() } }
     func begin() {
         realm.beginWrite()
     }
     func rollback() {
         realm.cancelWrite()

        close()
     }
     func commit() {
         try!realm.commitWrite()

        close()
     }
     func close() {
         //realm.refresh()  //TODO:調べて実装し直し

         //realm = nil //追記:参照を飛ばせばOKぽい? dispatchqueueの変数管理が必要か

    }

}

下のように修正(201190122)

tm-b.hatenablog.com

実装はとりあえずこれで

うごかせなかったので机上で実装しただけ。(動かないかも)
T.self -> javaだと可変長配列から型を引っ張るなど工夫がいりますが、SWIFTはシンプル

Realm、Androidとは要領が少し違いました。(パッと進みませんでした)、続きは今度

ab39