UIButton touch задерживается, когда в UIScrollView - PullRequest
49 голосов
/ 04 сентября 2010

Я столкнулся с небольшой проблемой в моем приложении.

По сути, у меня есть серия UIButtons, добавленная как подпредставление в UIScrollView, который является частью пера. Каждый раз, когда я нажимаю на кнопку, происходит заметная задержка, прежде чем кнопка будет выделена. По сути, мне нужно подержать ее примерно полсекунды, пока кнопка не потускнеет и не окажется выделенной.

Я предполагаю, что это потому, что UIScrollView должен определить, является ли касание прокруткой или это касание, предназначенное для подпредставления.

В любом случае, я немного не уверен, как поступить. Я просто хочу, чтобы кнопка казалась выделенной, как только я нажму на нее.

Любая помощь приветствуется!

Edit:

Я пытался установить delaysContentTouches на NO , но прокрутка становится практически невозможной, поскольку большая часть моего scrollView заполнена UIButtons.

Ответы [ 7 ]

48 голосов
/ 29 октября 2013

Решение Джеффа не совсем подходит для меня, но это похоже: http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

В дополнение к переопределению touchesShouldCancelInContentView в вашем подклассе вида прокрутки, вам все равно нужно установить delaysContentTouches на false. Наконец, вам нужно вернуть true вместо false для ваших кнопок. Вот модифицированный пример по ссылке выше. Как предложили комментаторы, он проверяет любой подкласс UIControl, а не UIButton, в частности, так что это поведение применяется к любому типу управления.

Objective-C:

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.delaysContentTouches = false;
    }

    return self;
}

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    if ([view isKindOfClass:UIControl.class]) {
        return true;
    }

    return [super touchesShouldCancelInContentView:view];
}

Swift 4:

override func touchesShouldCancel(in view: UIView) -> Bool {
    if view is UIControl {
        return true
    }
    return super.touchesShouldCancel(in: view)
}
40 голосов
/ 04 сентября 2010

Хорошо, я решил это путем создания подкласса UIScrollView и переопределения touchesShouldCancelInContentView

Теперь мой UIButton, который был помечен как 99 бликов, и мой скролл прокручивается!

myCustomScrollView.h

@interface myCustomScrollView : UIScrollView  {

}

@end

и myCustomScrollView.m :

@implementation myCustomScrollView

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view
    {
        NSLog(@"touchesShouldCancelInContentView");

        if (view.tag == 99)
            return NO;
        else 
            return YES;
    }
26 голосов
/ 04 сентября 2010

Попробуйте установить для свойства UIScrollView delaysContentTouches значение NO.

1 голос
/ 21 июля 2017

В Swift 3:

import UIKit

class ScrollViewWithButtons: UIScrollView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        myInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        myInit()
    }

    private func myInit() {
        self.delaysContentTouches = false
    }

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIButton {
            return true
        }
        return super.touchesShouldCancel(in: view)
    }
}

Затем вы можете использовать это ScrollViewWithButtons в IB или в коде.

1 голос
/ 17 января 2017

Решение раскадровки: выберите представление прокрутки, откройте «Инспектор атрибутов» и снимите флажок «Задержки касания содержимого» * ​​1001 *

enter image description here

0 голосов
/ 27 мая 2017

Swift 3:

scrollView.delaysContentTouches = false
0 голосов
/ 23 июля 2012

Ни одно из существующих решений не сработало для меня.Возможно, моя ситуация более уникальна.

У меня есть много UIButtons в пределах UIScrollView.При нажатии UIButton пользователю предоставляется новый UIViewController.Если кнопка нажата и удерживается достаточно долго, она покажет свое нажатое состояние.Мой клиент жаловался на то, что, если вы нажмете слишком быстро, депрессивное состояние не отобразится.

Мое решение: в методе UIButtons ', где я загружаю новый UIViewController и представляю его на экранеuse

[self performSelector:@selector(loadNextScreenWithOptions:) 
           withObject:options 
           afterDelay:0.]

Это планирует загрузку следующего UIViewController в следующем цикле событий.Время для перерисовки UIButton.UIButton теперь показывает свое депрессивное состояние перед загрузкой следующего UIViewController.

...