ObjectiveCを用いてiPhnoneアプリ開発の勉強をしています。
TableViewControllerのセルにUITextFieldを設置し、そのTextFieldをタッチして表示されたキーボードを
キーボードの外がタップされた時に引っ込める(隠す)処理をしたいのですが、うまくできませんでしたので助言をいただきたいです。
Tap Gesture Recognizerを用いる方法や
touchesBeganメソッドを用いてタップを検知し[self.view endEditing:YES];でキーボードを閉じる
という方法を試したのですが、これらたUIViewControllerでないとできないようで、
キーボードの外をタップしても、セルが選択されてしまい、キーボードは閉じませんでした。
この問題に関して、以下のサイトが参考になると思ったのですが、
http://onno.jp/dev/2012/02/uitableview-touchesbe …
>IB で TableView のクラスを TouchableTableView に変更
という部分が、どこを指しているのか分からず、どうしたら良いのか分かりません。
どこのTableViewのクラスを、TouchableTableViewに変更したら良いのでしょうか?
試しにキーボードを引っ込ませる処理を組み込みたいTableViewControllerのスーパークラスを
UITableViewController から TouchabeTableViewに変更してみましたが、うまくいきませんでした・・
タップした時にキーボードが引っ込ませたいTableViewControllerと、
新たに作成したTouchableTableViewはどのようにして関連付けるのでしょうか?
以下にTouchableTableViewのソースコードを書いておきます。
(Xcode6になり、Fileの新規作成画面が変わり、クラスの書き方がいつもと違うようになっているのが気になりますが・・・。)
-----------
■TouchableTableView.h
#import <UIKit/UIKit.h>
@interface UITableView (TouchableTableView)
@end
■TouchableTableView.m
#import "TouchableTableView.h"
@implemention UITableView (TouchableTableView)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
@end
---------
回答お願いします
No.2ベストアンサー
- 回答日時:
あなたが作ったTouchableTableView.mは「カテゴリ」が使われていますが、
既存のメソッド(touchesBegan)をカテゴリで上書きするのは大変危険なので
やめた方がよいです。カテゴリを使ってやってよいのは、既存クラスへの
メソッドの追加だけです。メソッドのオーバーライドは基本的に禁止と
考えるべきです。
(参考)
http://kurokawh.blogspot.jp/2010/03/objective-c. …
そもそも、あなたが参考にしたサイトは、カテゴリを使うように書かれていません。
「UITableView のサブクラス TouchableTableView を作成」と書かれており、
カテゴリじゃなくて、UITableViewを継承したサブクラスを作るように書かれています。
もしかして、あなた自身別にカテゴリを使う意図などないのに、
よくわからないまま適当にやって、結果的にカテゴリを使う形に
なってしまっているのではないですか?
>(Xcode6になり、Fileの新規作成画面が変わり、クラスの書き方がいつもと違うようになっているのが気になりますが・・・。)
と書かれていますが、Xcode6になったからといって、別にクラスの書き方は変わっていません。
ただ「New > File」メニューで表示される作成可能なファイル形式の
一覧表示がXcode5と6で若干異なっており、それで混乱しているの
ではないかと思います。
Xcode5で新規クラスファイルを作成するには、通常
「iOS」-「Cocoa Touch」-「Objective-C class」
を選択しますが、
Xcode6でそれに相当するのは
「iOS」-「Source」-「Cocoa Touch Class」
です。
「iOS」-「Source」-「Objective-C File」
というのもありますが、そちらを選ぶと
カテゴリ形式、プロトコル形式、クラス拡張形式のソースのひな型を
作ってしまいますので、誤ってそちらを選んで、意図せずカテゴリを
使ったソースを作ってしまったということはないでしょうか?
もしそうなら作り直した方がよいと思います。
> >IB で TableView のクラスを TouchableTableView に変更
> という部分が、どこを指しているのか分からず、どうしたら良いのか分かりません。
> どこのTableViewのクラスを、TouchableTableViewに変更したら良いのでしょうか?
ちゃんと「UITableView のサブクラス TouchableTableView を作成」できたなら
UITableViewController内のTable ViewのCustom ClassにTouchableTableViewを
指定できるようになるはずです。
それだけでもともとやりたかったことができるかどうかは、私自身検証したことなくて
今は検証する時間もないのでわかりませんが、少なくともそのサイトで書いているのは
カテゴリではなく、通常の継承を使った方法です。
回答ありがとうございます!
お察しの通り、カテゴリを使う意図はありませんでした・・すみません。
クラスファイルの作り方で迷い、カテゴリを選択してみた時に今までのようにヘッダファイルと実行ファイルが作成されたので、クラスの記述方法が変わったんだくらいに思ってました。
ファイルの新規作成方法まで丁寧に教えていただいてとても助かります。
教えていただいた通りにコードを記述し、サブクラスを指定したところ、セルをタップした時でもキーボードを引っ込められるように出来ました!
ただビューを移動するセルをタップすると、キーボードを引っ込めながらビューを移動してしまうので、
NSNotificationとUIKeyboardDidShowNotificationでキーボード表示をBOOL値を管理してキーボードが表示されている時は、キーボード外全体はキーボードを閉じるだけの処理というもともと考えていた動きを実装する事ができました!
あとはスクロール時の処理も組み込んでみたいと思います。
回答ありがとうございました!
No.1
- 回答日時:
その「TouchableTableView」というのは、Objective-Cのひとつの概念「カテゴリ」を利用したものです。
カテゴリはほかのオブジェクト指向の言語にはみられない、Objective-C独自のもので、ひじょうに強力で、それゆえ扱いに気をつけたほうがいいものです。カテゴリは、クラスのメソッドを上書きします。既存のFoundation、UIKitフレームワークのクラスも書き換え可能なので、使い方を間違えると、こわいことになりますね。UIScrollViewは、タッチイベント(touchesBegan:、touchesMoved:、touchesEnded:など)を上位のResponderに渡さない性質を持ちます。UITableViewは、UiScrollViewのサブクラスなので、おなじ性質です。これをカテゴリを使って、タッチイベントを上位のResponderに渡すようにします。
なお、カテゴリは別ファイルとして作成する必要はなく、プログラマの都合のいい場所に記述することができます。今回の例では、UIViewControllerサブクラスの実装ファイル(例:ViewController.m)に記述するといいでしょう。
#import "ViewController.h"
@interface UITableView (Touchable) // カッコ内は、カテゴリ名。任意です。好きな名称をつければいいです。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@implementation UITableView (Touchable)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesBegan: touches withEvent: event]; // タッチイベントを、つぎのResponderにそのまま渡す。
}
@end
@implementation ViewController
~中略
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES]; // タッチイベントを受け取ったら、キーボードを下げる。
}
~以下略
@end
「super touchesBegan: ~」は、記述しませんでしたが、必要かもしれません。いまのところ私には判断できません。
さて、以上のカテゴリを追加しても、キーボードは下がらないと思います。それは、じつはUITableViewCellもタッチイベントを止めてしまうからなのです。
UITableViewCellのサブクラスを実装していると思います。それにも、
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.nextResponder touchesBegan: touches withEvent: event]; // タッチイベントを、つぎのResponderにそのまま渡す。
}
を実装してください。そうすれば、テキストフィールド以外のタッチで、キーボードが下がるようになります。
なお、UIScrollViewのプロパティ「keyboardDismissMode」があって、この値を「UIScrollViewKeyboardDismissModeOnDrag」にすると、スクロールビュー(テーブルビュー)をスクロールすることで、キーボードを下げることができます。これはStoryboard上でも設定できるので、「それでもいいか」と思ったら、こちらを使うほうがかんたんです。
回答ありがとうございます!
意図せずカテゴリというものを使っていたようで、カテゴリというものを知りませんでした;すみません。
カテゴリというものについて少し調べてみましたが、既存のクラスにメソッドを追加できるそうですね。
確かに、やりようにやっては何でもできてしまいそうな印象で、それ故に扱いが難しそうです。
今回はカテゴリを使用せずに処理できるようなので使用せずにプログラムを組んでみようと思いますが、今後カテゴリを使う機会があった時、記述方法を参考にさせていただきます!
タップした時だけキーボードを閉じる仕様を考えていましたが、
スクロールした時は閉じないという仕様だと、動作がわずらわしいなと思ったので、
UIScrollViewのプロパティ「keyboardDismissMode」を使ってキーボードを閉じる処理にも挑戦してみようと思います
ありがとうございました
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
インナークラスについて
-
【C#】クラスのコンストラクタ...
-
委譲って何ですか?
-
interface,extend,implementの...
-
抽象クラスをJUNITでテストする...
-
JavaにListElement型ってあるん...
-
Excel vbaのプログラムでガンマ...
-
抽象クラスのエラーが出ます
-
cocoa、objective-cのクラスを...
-
単体テストのテストケースにて...
-
インタフェースのstatic変数(Java)
-
C#からDLLを呼びたいのですが・...
-
Java StringBuilderクラスについて
-
インターフェースとは
-
オブジェクト指向の本当の便利...
-
抽象クラスとインタフェースの...
-
タイマーの作り方
-
javaのabstractの意味
-
インターフェース型の使い方が...
-
Javaの自作例外クラスについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「ラッパークラス」の存在意義...
-
C# 「データが失なわれる可能性...
-
VB DLLプロジェクトについて
-
抽象クラスをJUNITでテストする...
-
「継承されたメソッドの可視性...
-
インターフェースとトレイトっ...
-
c++でのヘッダーファイルの循環...
-
JavaでのAPIの覚え方ってみさな...
-
(vba)他のアプリケーションの右...
-
ASP.NETでの共通コードの書き方...
-
なぜForm型にキャストするので...
-
vb.net 自作プロパティの削除に...
-
【C#】クラスのコンストラクタ...
-
委譲って何ですか?
-
interface,extend,implementの...
-
Javaのインスタンス化の構文の...
-
オーバーライドとラッパーの違い
-
Commons-Discovery.jarとは?
-
JTextFieldの入力制限
-
C#からDLLを呼びたいのですが・...
おすすめ情報