UITableViewCellに置いたボタンのイベント処理

2013.10.04 Friday 11:48
0
    画面に置いたUITableViewCellのボタンイベントってどうやって処理するのかなぁって思いました。


    単純な処理ならば、UITableViewCellを継承したクラス内でイベント処理をするのが一番簡単だと思います。
    でも、複雑な処理をしたい場合、UIViewControllerを継承したメインの画面側で処理を書く方がスマートな気がしてきました。


    ボタンイベントの取得

    こういう感じの各セルのボタンが押された時の処理をメイン画面側で行いたい(^^;;



    調べた内容を自分なりにまとめてみました。


    以下の例では「myButton」という名前のボタンに対して、addTargetを使ってボタンが押されたときに実行される「onMyButtonTouch」という任意の名前のメソッドを設定しています。

    そして、そのメソッド内では「myTable」というテーブルから現在押されたボタンのインデックスを取得してログ出力います。


    //---------------------------------
    // セルの内容表示
    //---------------------------------
    - (UITableViewCell*)tableView:(UITableView *)tableView
            cellForRowAtIndexPath:(NSIndexPath *) indexPath
    {
        static NSString* CellIdentifier = @"Cell";
        myTVCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            cell = [[myTVCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                            reuseIdentifier:@"myTVCell"];
        }
    
        // タッチイベントを追加    
        [cell.myButton addTarget:self action:@selector(onMyButtonTouch:event:)
                                            forControlEvents:UIControlEventTouchUpInside];
    
        
        return(cell);
    }
    
    
    //---------------------------------
    // ボタンが押された時の処理を記述
    //---------------------------------
    - (void)onMyButtonTouch: (UIButton *)sender
                      event:(UIEvent *)event
    {
        // 押されたボタンのセルのインデックスを取得
        UITouch *touch = [[event allTouches] anyObject];
        CGPoint point = [touch locationInView:_myTable];
        NSIndexPath *indexPath = [_myTable indexPathForRowAtPoint:point];
    
        // ログを出力    
        NSLog(@"row : %d", indexPath.row);
    }
    


    押されたボタンのセルの行番号が取得できたらもうこっちのものです(^-^)

    これでUIViewController側でUITableViewCellのイベント処理を記述できるようになりました。
    category:画面関連 | by:こもcomments(2) | - | -

    NSUnknownKeyExceptionが出た時の回避方法

    2013.09.25 Wednesday 12:30
    0
      画面のパーツとプログラムを繋ぐとき、[control] ボタンを押しながらヘッダファイルにマウスドロップすると自動で接続してくれるのはとても便利な機能です。

      しかし、よくやっちゃう失敗。
      それは……

      Action のつもりが、Outletとして接続してしまった!!


      あわててヘッダファイルから誤って追加されたIBOutletの1行を消す。


      そしたら、アプリを実行し、画面を読み込んだタイミングでこんな感じのエラーが出たことはないでしょうか?


      *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyViewController 0x759a870> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key onFavo.'



      僕はこのNSUnknownKeyExceptionの回避方法がずっと分からず、xibファイルを作り直したり、間違ったコードを放置したりと、ごまかしごまかし運用していました。

      たまたま解決方法を知る機会があったので、ブログに残しておきます。


      1. 画面の間違って接続したパーツを右クリック


      2. 「Referencing Outlets」という項目に接続したプロパティが表示されるので、「×」ボタンを押していらない接続を解除




      3. これで接続を解除できたので、ヘッダファイルのいらない1行を消す


      この手順で行うと、アプリ実行時にエラーがでることはなくなりました。



      解決。解決。ちょっと嬉しかったです。


      本などを読んできちんとiPhoneアプリの作り方を勉強している人にとっては、このあたりは当たり前のことなんでしょうが、僕はほとんど独学で作っていたのでけっこうハマっちゃいました(^^;;

      解決できてよかったです。
      category:画面関連 | by:こもcomments(5) | - | -

      ボタンを画像ボタンにする

      2013.08.07 Wednesday 09:42
      0
        ボタンを画像のボタンにする方法についてメモです。


        デフォルトではテキスト表示になっているボタン(Round Rect Button)に、自分で作った画像ファイルをセットして画像ボタンを作ります。



        ↓↓↓







        1. プロジェクト内のSupporting Filesに使用する画像ファイルをマウスでドロップします。





        2. Round Rect Buttonのプロパティを変更



        初期状態



        まず、画像をセットします。

        Imageのプルダウンメニューに「1.」でドロップした画像があるはずなので、それを選びます。





        すると、このようにボタンに画像が表示されるようになります。



        ……でも、ボタンの枠線が邪魔ですよね(^^;;

        なので、Typeを「Rounded Rect」から「custom」に変更して、枠線を無くします。






        これで画像のボタンができました。
        category:画面関連 | by:こもcomments(0) | - | -

        画面を縦方向に固定にする

        2013.07.25 Thursday 04:06
        0
          実機の端末の傾きによって、再描画処理が走って縦方向表示と横方向表示が切り替わったりします。

          縦向きのアプリを想定して作っていたので、これは困る……と思い、画面を縦方向表示に固定する方法を試してみました。



          最初はViewControllerのshouldAutorotateをオーバーライドして試していました。

          ……が、どうもうまく行かないタイミングがあったので、悩んでいました。

          - (BOOL)shouldAutorotate
          {
              return NO;
          }
          


          どうも、shouldAutorotateだけでは不足みたいですね(^^;;
          あんまり意味も分かってないままコピペしてきたので不覚でした(>_<)


          サポートする方向を返すsupportedInterfaceOrientationsもオーバーライドして縦方向表示にしないとダメなんですね。

          // 常に回転させない
          - (BOOL)shouldAutorotate
          {
              return NO;
          }
          
          // 縦のみサポート
          - (NSUInteger)supportedInterfaceOrientations
          {
              return UIInterfaceOrientationMaskPortrait;
          }
          



          念のため、TargetsのSummrayの「supported Interface Orientations」も通常の縦方向(Portrait)のみにしておきます。




          これでなんとか、縦方向のみ対応したアプリとして機能するようになりました。

          category:画面関連 | by:こもcomments(0) | - | -

          読み込み中などのクルクル画面を作ってみた

          2013.07.07 Sunday 00:07
          0
            検索や読み込み中など、非同期処理中に表示するクルクル画面を作ってみました。

            とりあえず、全面表示にして、中央にクルクル画像と処理中の文字を表示する感じです。




            転用しやすい用に、NSObjectを継承してクラス化し、Viewを動的に生成するようにしました。
            クルクルにはUIActivityIndicatorViewを使いました。


            @interface WaitingUtil : NSObject
            {
                UIActivityIndicatorView *m_indicatorView;
                UIView *m_loadingView;
                UILabel *m_labelView;
                
                BOOL m_Waiting;
            }
            
            - (id)init;
            
            - (void)startWaiting:(UIView *)view displayWord:(NSString *)word;
            - (void)stopWaiting;
            
            @end
            


            #import "WaitingUtil.h"
            
            @implementation WaitingUtil
            
            // 初期処理
            - (id)init
            {
                if(self == [super init]) {
                    m_Waiting = NO;
                }
            	
                return self;
            }
            
            // 待ち処理開始
            - (void)startWaiting:(UIView *)view
                displayWord:(NSString *) word
            {
                if(m_Waiting){
                    return;
                }
                m_Waiting = YES;
                
            
                // 各ビューを初期化
                m_loadingView = [[UIView alloc] 
                    initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
                [m_loadingView setBackgroundColor:[UIColor blackColor]];
                [m_loadingView setAlpha:0.5];
                
                m_indicatorView = [[UIActivityIndicatorView alloc]
                    initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
                
                // クルクルをセンタリング
                float w = m_indicatorView.frame.size.width;
                float h = m_indicatorView.frame.size.height;
                float x = view.frame.size.width / 2 - w / 2;
                float y = view.frame.size.height / 2 - h / 2;
                m_indicatorView.frame = CGRectMake(x, y, w, h);
                
                
                // クルクルの下に文字を表示
                float offsetY = y + h + 10;
                float fontSize = 16; // (任意のフォントサイズ)
                
                m_labelView = [[UILabel alloc] 
                    initWithFrame:CGRectMake(0, offsetY, view.frame.size.width, fontSize)];
                m_labelView.text = word;
                m_labelView.textColor = [UIColor whiteColor];
                m_labelView.backgroundColor = [UIColor clearColor];
                m_labelView.font = [UIFont fontWithName:@"AppleGothic" size:fontSize];
                m_labelView.textAlignment = NSTextAlignmentCenter;
                
                
                // クルクルを開始
                [m_indicatorView startAnimating];
                
                // ビューに追加する
                [view addSubview:m_loadingView];
                [view addSubview:m_indicatorView];
                [view addSubview:m_labelView];
             
                
            }
            
            
            // 待ち処理終了
            - (void)stopWaiting
            {
                // クルクルを停止
                [m_indicatorView stopAnimating];
                
                // ビューから消す
                [m_loadingView removeFromSuperview];
                [m_indicatorView removeFromSuperview];
                [m_labelView removeFromSuperview];
                
                m_Waiting = NO;
            }
            
            @end
            


            そして、呼び出し側の実装です。

            - (void)viewDidLoad
            {
                [super viewDidLoad];
              
                // 待ち処理開始
                m_WaitingUtil = [[WaitingUtil alloc] init];
                [m_WaitingUtil startWaiting:self.view displayWord:@"Loading..."];
                
            
                // 何かの非同期処理    
            }
            
            // コールバック用の関数(非同期処理終了後などに呼ばれるようにする)
            -(void)callbackFunc {    
                
                // 待ち処理停止
                [m_WaitingUtil stopWaiting];
            }
            
            

            こんな感じでいけるはず……。

            有効的に使えるかどうかは別として、とりあえず備忘録として…。
            category:画面関連 | by:こもcomments(0) | - | -

            Calender
                123
            45678910
            11121314151617
            18192021222324
            252627282930 
            << June 2017 >>
            Sponsored Link
            Selected entry
            Category
            Archives
            Recent comment
            • NSUnknownKeyExceptionが出た時の回避方法
            • NSUnknownKeyExceptionが出た時の回避方法
              atsushi
            • NSUnknownKeyExceptionが出た時の回避方法
              kanejun
            • UITableViewCellに置いたボタンのイベント処理
              こも
            • UITableViewCellに置いたボタンのイベント処理
              かつお
            • NSUnknownKeyExceptionが出た時の回避方法
              こも
            • NSUnknownKeyExceptionが出た時の回避方法
               
            • iOS7のベータ版を入れてみた
              こも
            • iOS7のベータ版を入れてみた
              梅雨
            • iOS7のベータ版を入れてみた
              こも
            Sponsored Link
            Link
            Profile
            Search
            Others
            Mobile
            qrcode
            Powered
            無料ブログ作成サービス JUGEM