71

私は同様のことに関するたくさんの投稿を見てきましたが、この問題に完全に一致したり修正したりするものはありません. iOS 7 以降、UIButtonaUITableViewCellまたはフッタービューに a を追加するたびに「正常に」動作します。つまり、ターゲット アクションを受け取りますが、 a をタップしたときに通常発生する小さなハイライトは表示されませんUIButton。タッチに反応するボタンを表示しないと、UI がファンキーに見えます。

これはiOS7のバグとして数えられると確信していますが、誰かが解決策を見つけたか、解決策を見つけるのを手伝ってくれました:)

編集:ボタンを長押しすると強調表示されることを忘れていましたが、標準ビューに追加した場合のようにすばやくタップすることはできません.

コード:

ボタンの作成:

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.titleLabel.font = [UIFont systemFontOfSize:14];
    button.titleLabel.textColor = [UIColor blueColor];
    [button setTitle:@"Testing" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchDown];
    button.frame = CGRectMake(0, 0, self.view.frame.size.width/2, 40);

私がテストしたこと:

//ジェスチャ レコグナイザUITableViewが邪魔になる場合に備えて、ジェスチャ レコグナイザを削除します。

for (UIGestureRecognizer *recognizer in self.tableView.gestureRecognizers) {
   recognizer.enabled = NO;
}

//Cell からジェスチャを削除する

for (UIGestureRecognizer *recognizer in self.contentView.gestureRecognizers) {
       recognizer.enabled = NO;
    }

//これは少し軽いタッチを示していますが、これは望ましい外観ではありません

button.showsTouchWhenHighlighted = YES;
4

17 に答える 17

92

そのテーブルビューでは、このプロパティを追加するだけです。

tableview.delaysContentTouches = NO;

そして、コードの下に追加したセルを開始した後に cellForRowAtIndexPath を追加します。iOS 6 と iOS 7 では、セルの構造が明らかに異なります
。iOS 7 では、UITableViewCell とコンテンツ ビューの間に UITableViewCellScrollView コントロールが 1 つあります。

for (id obj in cell.subviews)
{
    if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])
    {
        UIScrollView *scroll = (UIScrollView *) obj;
        scroll.delaysContentTouches = NO;
        break;
    }
}
于 2013-10-10T15:03:59.710 に答える
27

これを受け入れられた回答に追加しようとしましたが、うまくいきませんでした。特定のクラスを探すのではなく、セレクターに応答するものを探すので、これはセルの delaysContentTouches プロパティをオフにするより安全な方法です。

セル内:

for (id obj in self.subviews) {
     if ([obj respondsToSelector:@selector(setDelaysContentTouches:)]) {
          [obj setDelaysContentTouches:NO];
     }
}

テーブルビューで:

self.tableView.delaysContentTouches = NO;
于 2013-10-29T23:31:40.490 に答える
17

問題を解決するために私がしたことは、次のコードを使用した UIButton のカテゴリでした:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];


    [NSOperationQueue.mainQueue addOperationWithBlock:^{ self.highlighted = YES; }];
}


- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];

    [self performSelector:@selector(setDefault) withObject:nil afterDelay:0.1];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    [self performSelector:@selector(setDefault) withObject:nil afterDelay:0.1];
}


- (void)setDefault
{
    [NSOperationQueue.mainQueue addOperationWithBlock:^{ self.highlighted = NO; }];
}

UITableViewCellでボタンを押すとボタンが正しく反応し、UITableViewはdelaysContentTouches強制されていないため正常に動作します。

于 2014-07-04T12:21:30.790 に答える
5

UITableViewCell のテキストのみの UIButton がタッチ時に強調表示されないという同様の問題がありました。私にとってそれを修正したのは、buttonTypeをカスタムからシステムに戻すことでした。

delaysContentTouches を NO に設定すると、同じ UITableViewCell 内の画像のみの UIButton のトリックが実行されました。

self.tableView.delaysContentTouches = NO;

ここに画像の説明を入力

于 2015-07-22T15:13:37.167 に答える
5
    - (void)viewDidLoad
{

    [super viewDidLoad];


    for (id view in self.tableView.subviews)
    {
        // looking for a UITableViewWrapperView
        if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"])
        {
            // this test is necessary for safety and because a "UITableViewWrapperView" is NOT a UIScrollView in iOS7
            if([view isKindOfClass:[UIScrollView class]])
            {
                // turn OFF delaysContentTouches in the hidden subview
                UIScrollView *scroll = (UIScrollView *) view;
                scroll.delaysContentTouches = NO;
            }
            break;
        }
    }
}

ここに画像の説明を入力

于 2014-12-11T07:36:39.017 に答える
4

これは、上記の Raphaël Pinto の回答のSwiftバージョンです。彼にも賛成票を投じることを忘れないでください:)

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    super.touchesBegan(touches, withEvent: event)
    NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in self.highlighted = true }
}

override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
    super.touchesCancelled(touches, withEvent: event)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue()) {
        self.setDefault()
    }
}

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    super.touchesEnded(touches, withEvent: event)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue()) {
        self.setDefault()
    }
}

func setDefault() {
    NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in self.highlighted = false }
}
于 2015-01-21T11:33:57.190 に答える
1

受け入れられた答えは、私にとっていくつかの「タップ」で機能しませんでした。

最後に、次のコードを uibutton カテゴリ (/サブクラス) に追加すると、100% 動作します。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

self.backgroundColor = [UIColor greenColor];
[UIView animateWithDuration:0.05 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
    self.backgroundColor = [UIColor clearColor];

} completion:^(BOOL finished)
 {
 }];
[super touchesBegan:touches withEvent:event];

}
于 2014-02-28T11:29:58.790 に答える
0

iOS 7 および 8 の Swift でのソリューション:

最初にユーティリティ関数を書きました:

class func classNameAsString(obj: AnyObject) -> String {
    return _stdlib_getDemangledTypeName(obj).componentsSeparatedByString(".").last!
}

次に、UITableView をサブクラス化し、これを実装します。

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    for view in self.subviews {
        if (Utility.classNameAsString(view) == "UITableViewWrapperView") {
            if view.isKindOfClass(UIScrollView) {
                var scroll = (view as UIScrollView)
                scroll.delaysContentTouches = false
            }
            break
        }
    }
}

また、UITableViewCell をサブクラス化し、これを実装します。

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    for view in self.subviews {
        if (Utility.classNameAsString(view) == "UITableViewCellScrollView") {
            if view.isKindOfClass(UIScrollView) {
                var scroll = (view as UIScrollView)
                scroll.delaysContentTouches = false
            }

        }
    }
}

私の場合、init(coder:) が実行されます。どのinit関数が実行されるかを知るためにinit関数にデバッグポイントを入れてから、上記のコードを使用してそれを機能させてください。誰かを助けることを願っています。

于 2015-05-12T08:06:49.083 に答える