Hatena::ブログ(Diary)

日常茶飯事 このページをアンテナに追加 RSSフィード

2015-02-20

Swift 入力欄を作りたいけど、キーボードが出ると入力欄が埋まる罠 その2

| 18:41 | Swift 入力欄を作りたいけど、キーボードが出ると入力欄が埋まる罠 その2を含むブックマーク

新しいエントリーあります。

入力欄を作りたいけど、キーボードが出ると入力欄が埋まる罠 その3 リベンジ編

http://d.hatena.ne.jp/factory-g/20150705#1436109602


それならObjectCから

http://xyk.hatenablog.com/entry/2014/10/02/181047

上記ブログを参考にしつつ、いろいろマージしてみる。

UITextViewのデリゲートできてませんがな

http://stackoverflow.com/questions/25064465/uitextview-data-change-swift

(つд⊂)ううぅぅ

とにかく、こういった初歩的な所から盛大にずっこけてしまう・・・・

出来上がったソース

勿論、先ほどまで参考にしたブログ様と似たりよったりです。

半分以上意味わからずコーディングしてますわ。

import UIKit

class ViewController: UIViewController, UITextViewDelegate {
    @IBOutlet weak var txtChat: UITextField!
    @IBOutlet weak var scvBackGround: UIScrollView!
    @IBOutlet weak var tvChat: UITextView!
    
    @IBAction func tapScreen(sender: UITapGestureRecognizer) {
        self.view.endEditing(true)
    }
    var txtActiveField: UITextField?
    var txtActiveView: UITextView?
    
    // 最初に呼び出される
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tvChat.delegate = self
    }

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

    // テキストフィールドにフォーカスが移った場合
    func textFieldShouldBeginEditing(textField: UITextField!) -> Bool {
        txtActiveField = textField
        return true
    }

    // テキストフィールドからフォーカスが失われた場合
    func textFieldDidEndEditing(textField: UITextField!) -> Bool {
        if textField == txtActiveField {
            txtActiveField = nil
        }
        return true
    }
    
    // テキストビューにフォーカスが移った場合
    func textViewShouldBeginEditing(textView: UITextView!) -> Bool {
        txtActiveView = textView
        return true
    }
    
    // テキストビューからフォーカスが失われた場合
    func textViewShouldEndEditing(txtView: UITextView) -> Bool {
        if txtView == txtActiveView {
            txtActiveView = nil
        }
        return true
    }
    
    
    // キーボードのリターンキーを押された時にキーボードを閉じる
    /*
    func textFieldShouldReturn(textField: UITextField!) -> Bool {
        self.view.endEditing(true)
        return true
    }
    */
    
    // キーボード表示前のイベントhandleKeyboardWillShowNotification
    // キーボード非表示前のイベントhandleKeyboardWillHideNotification
    // を登録
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
        let notificationCenter = NSNotificationCenter.defaultCenter()
        notificationCenter.addObserver(self, selector: "handleKeyboardWillShowNotification:", name: UIKeyboardWillShowNotification, object: nil)
        notificationCenter.addObserver(self, selector: "handleKeyboardWillHideNotification:", name: UIKeyboardWillHideNotification, object: nil)
    }

    // キーボードが表示された時
    func handleKeyboardWillShowNotification(notification: NSNotification) {
        // キーボードのTOPを取得
        let userInfo = notification.userInfo!
        let keyboardRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
        let myBoundSize: CGSize = UIScreen.mainScreen().bounds.size
        
        var txtFieldRect: CGRect!
        if txtActiveField != nil {
            txtFieldRect = txtActiveField?.frame
        }
        if txtActiveView != nil {
            txtFieldRect = txtActiveView?.frame
        }
        
        // キーボードに隠れない場合は、何もしない
        if CGRectGetMaxY(txtFieldRect!) < CGRectGetMinY(keyboardRect){
            return
        }
        var nowOffsetY:CGFloat = scvBackGround.contentOffset.y
        
        // スクロールさせる距離を算出
        var offsetY:CGFloat = CGRectGetMaxY(txtFieldRect!) - CGRectGetMinY(keyboardRect)

        // scrollView の contentInset と scrollIndicatorInsets の bottom に追加
        var contentInsets:UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, offsetY, 0.0)
        scvBackGround.contentInset = contentInsets
        scvBackGround.scrollIndicatorInsets = contentInsets

        // 移動後のオフセット算出
        var scrollPoint:CGPoint = CGPointMake(0.0, nowOffsetY + offsetY + 65.0)
        
        UIView.beginAnimations(nil, context: nil)
        UIView.setAnimationDuration(userInfo[UIKeyboardAnimationDurationUserInfoKey] as double_t)
        // エラーになります。ワカランがぁ。
        // UIView.setAnimationCurve((userInfo[UIKeyboardAnimationCurveUserInfoKey] as NSValue) as integer_t)
        UIView.setAnimationBeginsFromCurrentState(true)
        
        // 移動後のオフセット設定
        scvBackGround.contentOffset = scrollPoint
        
        UIView.commitAnimations()
        
    }
    
    // ずらした分を戻す
    func handleKeyboardWillHideNotification(notification: NSNotification) {
        scvBackGround.contentOffset.y = 0
    }

    
    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        
        let notificationCenter = NSNotificationCenter.defaultCenter()
        notificationCenter.removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
        notificationCenter.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }


}

キーボードの候補欄の高さが

初回呼び出しに限り取得できません!!!

ッテナンデヤネン┌(`Д´)ノ

もう、ほっときますわ。これ。

二回目からはちゃんと行くから。

総括

スクロールコントロールが無いと、出来ないとか、ドンだけテクニックが必要なん↑

疲れた。

Table関連での入力で参考になりそうなブログ

http://redwing.moo.jp/cocoa/archives/783

さて、iOS8から参戦した弩素人、これからChatまで結びつけられるのか・・・。

Swift 入力欄を作りたいけど、キーボードが出ると入力欄が埋まる罠

| 15:55 | Swift 入力欄を作りたいけど、キーボードが出ると入力欄が埋まる罠を含むブックマーク

Swiftというより、モバイル開発弩級素人が、砂粒パウダーに躓いて大怪我している実況です。


まず、こんなの楽勝じゃね?とか思った、入力ですが、ちゃんといろいろ成立させようとすると、無茶苦茶コーディングしないと馬犬 目 ぽ..._φ(゚∀゚ )アヒャって事がわかりました。

iOS系のプログラマの皆さんのスキルぱねぇっす。

なんせ、キーボードが、画面したからせり上がって来なさる。なので、画面下部に設定したテキストフィールドは、隠れておしまいになる。

しかも、画面を横にすると、キーボードの大きさが変わって、よりきめ細かな制御が必要・・・。

ちまたの入門書だと、触れもしない所で、正直こういった細かな制御しらないと、アプリ販売とか一生無理だと思い知らされましたよ。

でもめげません。

取り敢えず、参考になりそうなブログをば

http://ameblo.jp/hayashidesuga/entry-11971210696.html

http://qiita.com/sasagin/items/f2d5e8cb35e3b7091942

実は上記で実装したのですが、以下の問題がでて、朝からもれのCPUが火を噴いている状態。

キーボード画面最上部の候補欄分がどうも取得できない。

チャットだから改行もしたいけど、改行が打てない。

・UITextViewのスクロールが思った感じにならない・・・。

・Messengerアプリよろしく入力欄が自動でデカくなって欲しい(後回し)

うううう、今日中には何とかしたいっす。

しっかし、キーボードをハード側から追い出した結果、あの製品が生まれたとはいえ、プログラマが大迷惑になってしまったという、笑えない現実があるんですね。

くっそ、面倒臭いっす。

全てのモバイルプログラマに幸アレ!!!