คุณสามารถแนบ UIGestureRecognizer กับหลายมุมมองได้หรือไม่?


228
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

ในรหัสข้างต้นก๊อกเท่านั้นที่view2ได้รับการยอมรับ หากฉันใส่ความคิดเห็นในบรรทัดที่สามview1จะมีการจดจำการแตะ หากฉันพูดถูกและคุณสามารถใช้ตัวจำแนกลายมือเพียงครั้งเดียวฉันไม่แน่ใจว่านี่เป็นข้อบกพร่องหรือไม่ก็ต้องการเอกสารเพิ่มเติมอีก

คำตอบ:


334

A UIGestureRecognizerจะใช้กับมุมมองเดียว ฉันเห็นด้วยว่าเอกสารนั้นขาด ๆ หาย ๆ ที่UIGestureRecognizerมีviewคุณสมบัติเดียวให้มันไป:

ดู

มุมมองตัวรู้จำท่าทางที่แนบมากับ (อ่านเท่านั้น)

@ คุณสมบัติ (ไม่ใช่เชิงอะตอมอ่านอย่างเดียว) UIView * ดู

การสนทนาคุณแนบ (หรือเพิ่ม) ตัวรู้จำท่าทางสัมผัสกับวัตถุ UIView โดยใช้วิธีการ addGestureRecognizer:


11
เนื่องจากการเพิ่มตัวรู้จำท่าทางให้กับมุมมองเกิดขึ้นที่รันไทม์ (เทียบกับเวลารวบรวม)
TomSwift

1
ฉันได้รับแล้ว แต่เหมือนกับการตรวจจับที่บอกว่าเราไม่ได้ใช้ตัวแปร XCode สามารถบอกได้ตามรหัสที่เราได้ใช้ตัวจดจำเดียวกันไปยังหลายมุมมองและสามารถเตือน coder ได้
ZoltánMatók

1
คอมไพเลอร์คำเตือนเกี่ยวกับหลายมุมมองที่กำหนด UITapGestureRecognizer เดียวกันนั้นเป็นเรื่องไร้สาระเนื่องจากคุณอาจต้องการทำสิ่งนี้โดยเจตนาตัวอย่างเช่นถ้าคุณต้องการย้ายตัวรู้จำท่าทางแตะจากมุมมองหนึ่งไปอีกมุมมองหนึ่ง ที่กล่าวว่าเป็นข้อ จำกัด ที่ไม่สามารถใช้ตัวจดจำท่าทางในหลาย ๆ มุมมองได้
Erik van der Neut

1
ตอนนี้ iOS 9 บังคับให้ใช้มุมมองเดียวต่อตัวจดจำท่าทางฉันใช้วิธีการสร้างอินเตอร์เฟสด้านล่าง แต่ตอนนี้ฉันได้รับข้อความต่อไปนี้เมื่อฉันพยายามใช้งาน (รายละเอียดบางอย่างถูกตัดให้สั้นลง): คำเตือน: เครื่องมือจดจำท่าทาง (< UITapGestureRecognizer: ..... >) ถูกติดตั้งในสตอรีบอร์ด / xib ที่จะเพิ่มในมุมมองมากกว่าหนึ่งมุมมอง (-> <UIView:; frame = (0 44; 600 536); ปรับขนาดอัตโนมัติ = RM + BM; gestureRecognizers = < NSArray ... :>; layer = <CALayer: ... >>) ต่อครั้งสิ่งนี้ไม่ได้รับอนุญาตและถูกบังคับใช้ในขณะนี้ เริ่มต้นด้วย iOS 9.0 มันจะถูกใส่ในมุมมองแรกที่มันถูกโหลดเข้ามา
George Brown

หากคุณกำลังเพิ่มการดูในครั้งที่สองมุมมองจะถูกแนบไว้ก่อนหน้านี้โดยตัวจำแนกลายมือนี้กำลังรับการเชื่อมต่อโดยอัตโนมัติUITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didPressed:)]; [self.view1 addGestureRecognizer:tapRecognizer]; [self.view2 addGestureRecognizer:tapRecognizer];เอาท์พุทview1 ไม่มีอาร์เรย์ตัวจดจำท่าทางสัมผัส view2 ได้รับอาร์เรย์ตัวจดจำท่าทาง
kokos8998

48

ฉันได้รอบโดยใช้ด้านล่าง

for (UIButton *aButton in myButtons) {

            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
            longPress.minimumPressDuration=1.0;
            [aButton addGestureRecognizer:longPress];
            [longPress release];

}

จากนั้นในวิธี handleLongPress ของฉันฉันเพิ่งตั้งค่า UIButton ให้เท่ากับมุมมองของตัวรู้จำท่าทางและแยกส่วนสิ่งที่ฉันทำตามปุ่มนั้น

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}

1
คำตอบที่ดีขอบคุณมาก นี่อาจเป็นคำตอบที่ยอมรับได้หากคำถามคือ "คุณแนบ UIGestureRecognizer กับมุมมองหลายมุมมองได้อย่างไร"
D_D

7
สิ่งนี้ (หรือบางสิ่งที่ใกล้เคียงกับนี้) ไม่ได้ผลสำหรับฉัน ฉันเพิ่มหลายมุมมองให้กับตัวจดจำท่าทางการแตะในตัวสร้างส่วนต่อประสานและเชื่อมต่อตัวจำแนกลายมือกับการกระทำ การดำเนินการถูกเรียกเมื่อใดก็ตามที่มีการแตะมุมมองที่แนบไว้ แต่ gesture.view เป็นมุมมองสุดท้ายที่แนบมาเสมอ
Aneil Mallavarapu

นี่เป็นคำตอบที่ดีมากและเป็นประโยชน์และเห็นด้วยกับ @MicRO +1
Dilip

2
ใช่นั่นเป็นเพราะคุณไม่ได้สร้างอินสแตนซ์ใหม่ของตัวจดจำท่าทาง สิ่งที่เกิดขึ้นในลูปของคำตอบนี้ตรงนี้คืออินสแตนซ์ใหม่ของตัวจดจำท่าทางสัมผัสถูกสร้างขึ้นแต่ละอันมีเพียงหนึ่งมุมมองที่แนบ พวกเขาสามารถชี้ไปที่ตัวจัดการเดียวกันซึ่งคุณจะตรวจสอบมุมมองเพื่อดูว่าอันไหนถูกแตะ
Erik van der Neut

1
คนอื่นสามารถยืนยันได้หรือไม่ว่านี่ไม่สามารถใช้งานได้ใน Obj-C / Swift เวอร์ชันปัจจุบันอีกต่อไป
Maxi Mus

18

สำหรับ Swift 3 ในกรณีที่ทุกคนต้องการ: จาก Bhavik Rathod คำตอบข้างต้น

 func setGestureRecognizer() -> UIPanGestureRecognizer {

        var panRecognizer = UIPanGestureRecognizer()

        panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
        panRecognizer.minimumNumberOfTouches = 1
        panRecognizer.maximumNumberOfTouches = 1
        return panRecognizer
    }

        ///set the recognize in multiple views
        view1.addGestureRecognizer(setGestureRecognizer())
        view2.addGestureRecognizer(setGestureRecognizer())

3
ที่โดยทั่วไปแล้วจะสร้างท่าทางหลายท่าทางสำหรับทั้งสองมุมมองกฎเดียวกัน: ทุกท่าทางมีเพียงมุมมองเดียวที่จะแนบไป
Abdoelrhman

3
ไม่ฟังก์ชันสร้างท่าทางทุกครั้งที่เรียกว่า
Abdoelrhman

2
ชื่อฟังก์ชั่นไม่ถูกต้อง ฟังก์ชันลอจิคัลนี่คือฟังก์ชั่นการรับ ดังนั้นจึงควรตั้งชื่อ: getGestureRecognizeเพราะนั่นคือสิ่งที่ฟังก์ชั่นนี้ทำ
David Seek

ทำงานได้ดีสำหรับฉัน! และโค้ดสะอาดกว่าสร้างตัวแปรหลายตัวหรือใส่รหัสทั้งหมดเพื่อสร้างใน addGestureRecognizer
Codenator81

11

เราสามารถทำอะไรเช่นนี้มันง่ายและเรียบง่าย

1) สร้างฟังก์ชั่นด้านล่างในคอนโทรลเลอร์ของคุณ (ฟังก์ชั่นนี้จะคืนค่า GestureRecognizer)

-(UITapGestureRecognizer*)setRecognizer{
     UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
     [gestureRecognizer setNumberOfTapsRequired:1];
     return gestureRecognizer;
}

2) ตั้งค่าตัวจำแนกนี้ในหลายมุมมอง

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];

มันไม่ทำงานสำหรับฉันเมื่อฉันใช้สองป้ายกำกับแทนการดู
Mihir Oza

3
@Mihir Oza ไม่สามารถทำงานกับ UILabels ได้โดยตรง เนื่องจากป้ายกำกับไม่สมเหตุสมผลสำหรับการโต้ตอบกับผู้ใช้ ถ้าคุณต้องการเพิ่มท่าทางสำหรับ UILabels ให้เพิ่ม label บรรทัดเดียวชื่อนี้ .. isUserInteractionEnabled = trueใน Swift จากนั้นเพิ่มท่าทาง
iOS

มันเป็นผู้ชายที่สายเกินไปฉันได้แก้ไขแล้ว แต่ขอบคุณสำหรับคำแนะนำ ความคิดเห็นของคุณจะเป็นประโยชน์สำหรับผู้ใช้งานสแต็ค ชื่นชม!
Mihir Oza

1
ฉันเดาว่าสายsetNumberOfTapsRequired:1ไม่จำเป็น
Abbas Naveed

9

ไม่คุณไม่ควรแนบตัวจดจำท่าทางสัมผัสกับมุมมองมากกว่าหนึ่งมุมมอง

มีข้อมูลที่ชัดเจนในเอกสารประกอบของ Apple:

ตัวจดจำท่าทางติดอยู่กับมุมมอง

ตัวรู้จำท่าทางทุกตัวนั้นเชื่อมโยงกับหนึ่งมุมมอง ในทางตรงกันข้ามมุมมองสามารถมีตัวจำแนกท่าทางหลายอย่างเนื่องจากมุมมองเดียวอาจตอบสนองต่อท่าทางที่แตกต่างกัน เพื่อให้ระบบรู้จำท่าทางสัมผัสเพื่อจดจำสัมผัสที่เกิดขึ้นในมุมมองเฉพาะคุณต้องแนบตัวรู้จำท่าทางเข้ากับมุมมองนั้น

คู่มือการจัดการกิจกรรมสำหรับ iOS - ตัวจดจำท่าทาง Apple Developer Library

ในขณะที่คนอื่นพูดถึงพวกเขาอาจทำงานในบางกรณีมันชัดเจนกับเอกสารประกอบและสามารถเปลี่ยนแปลงในเวอร์ชัน iOS ในอนาคต

สิ่งที่คุณสามารถทำได้คือเพิ่มตัวรู้จำท่าทางที่แยกต่างหากให้กับมุมมองที่คุณต้องการตรวจสอบและพวกเขาสามารถแบ่งปันการกระทำร่วมกัน


4

ดีถ้ามีคนไม่ต้องการรหัสสำหรับการเพิ่มมุมมองท่าทางสำหรับหลายปุ่มเช่นkwalkerได้ตอบข้างต้นและต้องการที่จะทำผ่านตัวสร้างส่วนติดต่อซึ่งอาจช่วยคุณได้

1) คุณสามารถเพิ่มตัวรู้จำท่าทางกดแบบยาวจากคลังวัตถุเช่นเดียวกับที่คุณเพิ่มวัตถุอื่น ๆ เช่น UIButtons และ UILabels

ป้อนคำอธิบายรูปภาพที่นี่ ตอนแรกสิ่งที่ฉันใช้คือฉันเอาแค่อันเดียว

2) ตั้งค่าช่องอ้างอิงUIButtonและส่งการกระทำกับเจ้าของไฟล์

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุ: หากคุณมี UIButton หลายตัวหรือวัตถุอื่นคุณจะต้องใช้ตัวจำแนกท่าทางแยกต่างหากสำหรับแต่ละรายการ สำหรับรายละเอียดเพิ่มเติมโปรดดูที่คำถามของฉัน รับแท็ก UIButton ที่ผิดบนตัวกดลายนิ้วมือกดแบบยาว


เป็นเรื่องง่ายมากที่จะผูก UIView มากกว่าหนึ่งตัวกับโปรแกรมจดจำเสียง guesture โดยใช้ IB คำถามคือเกี่ยวกับการสร้างรหัส
AlexeyVMP

3

หากคุณมีมุมมองคงที่ฉันขอแนะนำให้คุณทำสิ่งนี้

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

วิธีนั้นจะลดตัวแปรที่ไร้ประโยชน์หลายตัว


3

คุณสามารถสร้างส่วนขยายทั่วไปในมุมมองเพื่อเพิ่มตัวรู้จำท่าทางได้อย่างง่ายดาย นี่เป็นเพียงตัวอย่าง แต่อาจมีลักษณะเช่นนี้

extension UIView {

    func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
    let getRecognizer = type.init(target: target, action: actionSelector)

    switch getRecognizer {
    case let swipeGesture as UISwipeGestureRecognizer:
        guard let direction = swipeDirection else { return }
        swipeGesture.direction = direction
        self.addGestureRecognizer(swipeGesture)
    case let tapGesture as UITapGestureRecognizer:
        tapGesture.numberOfTapsRequired = numOfTaps
        self.addGestureRecognizer(tapGesture)
    default:
        self.addGestureRecognizer(getRecognizer)
    }
  }

}

วิธีเพิ่มตัวจำแนกลายมือแบบแตะ 2 อันบนมุมมองที่คุณเพิ่งจะเรียก:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

คุณสามารถเพิ่มตัวรู้จำการปัดได้อย่างง่ายดาย

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

และอื่น ๆ เพียงจำไว้ว่าเป้าหมายจะต้องเชื่อมโยงกับตัวเลือก


2

แทนที่คลาสด้วย ' <UIScrollViewDelegate>'

และใช้วิธีนี้ในคลาส. m:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

วิธีนี้จะช่วยให้คุณเปิดใช้งานการปัดหลายครั้งในมุมมองเดียว ..


2

สิ่งที่เกี่ยวกับการเขียน (สร้าง) GestureRecognize ของคุณใหม่ทุกครั้งที่คุณเพิ่มตัวจำแนกท่าทางที่ชี้ไปยัง func เดียวกัน ในกรณีด้านล่างมันใช้งานได้ ฉันใช้ IBOutletCollection

สวิฟท์ 2:

@IBOutlet var topicView: [UIView]!

override func viewDidLoad() {
        for view in self.topicView as [UIView] {
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
    }
}

func viewClicked(recognizer: UITapGestureRecognizer) {
    print("tap")
}

-6

คุณสามารถทำได้โดยใช้รหัสนี้มุมมองของฉันซึ่งเป็นภาพตัวอย่างใน xib

- (void)viewDidLoad
{
    firstIV.tag = 501;
    secondIV.tag = 502;
    thirdIV.tag = 503;
    forthIV.tag = 504;

    [self addTapGesturetoImageView: firstIV];
    [self addTapGesturetoImageView: secondIV];
    [self addTapGesturetoImageView: thirdIV];
    [self addTapGesturetoImageView: forthIV];
}

-(void)addTapGesturetoImageView:(UIImageView*)iv
{
    iv.userInteractionEnabled = YES;
    UITapGestureRecognizer * textfielBGIVTapGasture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textfielBGIVTapped:)];
    textfielBGIVTapGasture.numberOfTapsRequired = 1;
    [iv addGestureRecognizer:textfielBGIVTapGasture];
}

- (void)textfielBGIVTapped:(UITapGestureRecognizer *)recognizer {
    int tag = recognizer.view.tag-500;
    switch (tag) {
        case 1:
        {
            //firstIV tapped;
            break;
        }
        case 2:
        {
            //secondIV tapped;
            break;
        }
        case 3:
        {
            //thirdIV tapped;
            break;
        }
        case 4:
        {
            //forthIV tapped;
            break;
        }
        default: {
            break;
        }
    }
}

1
คุณกำลังสร้างตัวจดจำท่าทางหลายอย่าง คำถามเดิมของฉันเกี่ยวกับการนำตัวรู้จำท่าทางเดียวมาใช้ซ้ำซึ่งคุณไม่สามารถทำได้
kubi

1
การเพิ่ม500แท็กมุมมองทั้งหมดของคุณคืออะไรและลบออกแล้ว500? ทำไมไม่เพียงแค่เริ่มต้นที่แท็กของคุณ1(หรือแม้กระทั่ง0) แทน501?
ma11hew28

@MattDiPasquale, ไม่สำคัญว่าถ้าคุณต้องการที่จะเริ่มต้นด้วยการเป็นเพียงแค่ผมได้คัดลอกโค้ดนี้จากการตรวจสอบของฉันที่ฉันให้มันจาก1 501แต่ใช่ไม่ได้ให้0bcoz ฉันได้อ่านที่ไหนสักแห่งว่ามันมักจะบ่งบอกถึงมุมมองผู้ปกครองดังนั้นมันจะสร้างความซับซ้อนเชื่อฉันฉันได้เผชิญหน้ากับมัน
Dilip

ข้อความสำคัญในเอกสารประกอบคือ "มุมมองสร้างการอ้างอิงที่รัดกุมกับตัวรู้จำท่าทาง" ซึ่งหมายความว่ามุมมองที่เป็นเจ้าของท่าทาง ท่าทางสัมผัสมีเจ้าของได้คนเดียวเท่านั้น ดูลิงค์
Phantom59
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.