2010-09-04 9 views
43

Ich stoße auf ein kleines Problem in meiner App.UIButton touch ist verzögert, wenn in UIScrollView

Ich habe im Wesentlichen eine Reihe von UIButtons hinzugefügt als Subviews in einer UIScrollView, die Teil einer Feder ist. Jedes Mal, wenn ich auf einen Knopf tippe, gibt es eine merkliche Verzögerung, bevor der Knopf hervorgehoben wird. Ich muss es im Wesentlichen eine halbe Sekunde halten, bevor die Schaltfläche abgeblendet wird und ausgewählt erscheint.

Ich nehme an, dies ist, weil die UIScrollView feststellen muss, ob die Berührung eine Rolle ist oder ob es eine Berührung ist, die für eine Unteransicht gedacht ist.

Wie auch immer, ich bin ein wenig unsicher, wie es weitergeht. Ich möchte einfach, dass die Schaltfläche ausgewählt wird, sobald ich sie antippen.

Jede Hilfe wird geschätzt!

Edit:

Ich habe versucht, delaysContentTouches-NO Einstellung aber Scrollen wird fast unmöglich, da ein Großteil meiner Scrollview mit UIButtons gefüllt ist.

+0

Betrachten Sie diese Antwort anstelle der akzeptierten Antwort: http://stackoverflow.com/a/19656611/378024 – galambalazs

Antwort

39

Ok habe ich dies durch UIScrollView und überwiegende touchesShouldCancelInContentView

Subklassen gelöst Nun mein UIButton, die als 99 Highlights markiert wurde richtig und meine Scroll rollt!

myCustomScrollView.h:

@interface myCustomScrollView : UIScrollView { 

} 

@end 

und myCustomScrollView.m:

@implementation myCustomScrollView 

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

     if (view.tag == 99) 
      return NO; 
     else 
      return YES; 
    } 
+6

Wow, ich bin gerade auf diese Antwort gestoßen und es hat das Problem, das ich hatte, vollständig gelöst. Ich wünschte, ich könnte dir +1000 Punkte geben! Ich danke dir sehr. –

+0

funktioniert nicht in meinem Fall, aber es ist sehr nah an Ihrem. (Nur im Simulator getestet). Vielleicht ist diese Lösungszeit abgelaufen. –

+0

Swift Version unten, lesen Sie weiter ... –

25

Versuchen Sie, die Eigenschaft UIScrollView delaysContentTouches auf NO zu setzen.

+1

Sorry, ich hätte wahrscheinlich klarer sein sollen. Wenn ich delaysContentTouches auf NO setze, reagiert die Berührung sofort. Ein Scrollen wird jedoch fast unmöglich, da Berührungen eher als Tastenbetätigungen denn als tatsächliches Scrollen interpretiert werden. – Jeff

+0

@Jeff Sie können 'canCancelContentTouches' verwenden, um Scrollen zu ermöglichen, auch wenn die Berührung anfänglich als Schaltfläche behandelt wird, solange die Ziele der Berührung die Aufhebung unterstützen. Die Tasten werden anfänglich immer noch hervorgehoben, wenn Sie sie berühren, aber sobald Sie mit dem Scrollen beginnen, wird die Beleuchtung aufgehoben. – devios1

+0

@chaiguy Ich suche dieses Verhalten, genau wie du beschrieben hast, aber bisher kein Glück. Wenn ich 'delaysContentTouches = NO' und' canCancelContentTouches = YES' eingestellt habe, kann ich nicht scrollen, wenn ich UIButton überhaupt berühre. – Darrarski

0

Keine der bestehenden Lösungen für mich gearbeitet. Vielleicht ist meine Situation einzigartiger.

Ich habe viele UIButtons innerhalb einer UIScrollView. Wenn eine UIButton gedrückt wird, wird dem Benutzer eine neue UIViewController angezeigt. Wenn eine Taste lang genug gedrückt gehalten wird, zeigt die Taste ihren gedrückten Zustand an. Mein Kunde hat sich darüber beschwert, dass wenn Sie zu schnell tippen, kein gedrückter Zustand angezeigt wird.

Meine Lösung: Im Inneren des UIButtons 'Tap-Methode, wo ich die neue UIViewController laden und präsentieren sie auf dem Bildschirm, verwende ich

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

Diese Zeitpläne das Laden der nächsten UIViewController auf der nächsten Ereignisschleife. Lassen Sie Zeit für die UIButton neu zeichnen. Die UIButton zeigt jetzt ihren gedrückten Zustand vor dem Laden der nächsten UIViewController.

37

Jeffs Lösung war nicht ganz für mich zu arbeiten, aber dies ähnlich tut: http://www.charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state/

Nicht sicher, ob dies der Fall für Jeffs Antwort war, aber zusätzlich -touchesShouldCancelInContentView: in Ihrer Ansicht blättert Unterklasse zu überschreiben, können Sie immer noch muss delaysContentTouches auf NO eingestellt werden. Zu guter Letzt, anstatt NO für Ihre Schaltflächen zurückzugeben, müssen Sie YES zurückgeben. Hier ist ein Beispiel aus dem obigen Link.

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

    return self; 
} 

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

    return [super touchesShouldCancelInContentView:view]; 
} 

Schnelle Version.

override func touchesShouldCancelInContentView(view: UIView!) -> Bool { 
    if view is UIButton { 
     return true 
    } 
    return super.touchesShouldCancelInContentView(view) 
} 
+3

das funktioniert für mich und nicht die akzeptierte Antwort. Vielen Dank. –

+3

Ausgezeichnete Lösung! Wenn Sie den Schnittstellen-Builder verwenden, wählen Sie einfach die Bildlaufleiste aus und deaktivieren Sie im Attribut-Inspektor die Option "Verzögerungen bei Inhaltsberührungen". – Tim

+1

Arbeit für mich! Vielen Dank. – frank

0

Storyboard-Lösung: die Scroll-Ansicht wählen, öffnen Sie die "Attribute Inspector" und deaktivieren Sie "Delays Inhalt Touches"

enter image description here

0

Swift 3:

scrollView.delaysContentTouches = false 
1

In 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) 
    } 
} 

Sie können dann diese ScrollViewWithButtons in IB oder in Code verwenden.