Sobes.tech
Middle

როგორ დავადგინოთ, რომ მომხმარებელმა დაწკაპუნა ფენაზე (layer) აპლიკაციაში?

sobes.tech AI

პასუხი AI-სგან

CALayer-ზე დაჭერის განსაზღვრისთვის შეგიძლიათ გამოიყენოთ რამდენიმე მიდგომა:

  1. hitTest(_:event:) გამოყენება ხედში (View):

    • UIView აქვს მეთოდი hitTest(_:with:), რომელიც რეკურსიულად გადის ქვედა ხედების ჰიერქიასას და აბრუნებს ყველაზე ღრმა ქვედა ხედს, რომელიც შეიცავს მითითებულ წერტილს:
    • ამ მეთოდს დეფოლტად აქვს გათვალისწინებული ხედებთან დაკავშირებული ფენები:
    • შეგიძლიათ გადაწეროთ hitTest(_:with:) თქვენს პერსონალურ ხედზე უფრო დეტალური კონტროლის ან პირდაპირი დაჭერების დამუშავებისთვის ქვედა ფენებზე, რომლებიც არ არის დაკავშირებული ხედებთან:
  2. კოორდინატების გადაყვანა convert-ის საშუალებით:

    • როდესაც იღებთ შეხების მოვლენის (მაგალითად, UIView-ის მეთოდებში), გაქვთ კოორდინატები, რომლებიც დაკავშირებულია ფანჯარასთან (UIWindow) ან ხედთან:
    • რათა განსაზღვროთ, დაეცა თუ არა შეხება კონკრეტულ ფენაზე, საჭიროა ამ კოორდინატების გადაყვანა ამ ფენის კოორდინატულ სისტემაში:
    • ამისთვის გამოიყენება convert(_:from:) ან convert(_:to:) მეთოდები CALayer-ზე:
    • შემდეგ გადაყვანის შემდეგ, შეგიძლიათ შეამოწმოთ, არის თუ არა მიღებული წერტილი ფენის საზღვრებში (bounds) ან გამოიყენოთ უფრო სპეციფიკური შემოწმებები, მაგალითად, contains(_:):
  3. UITapGestureRecognizer-ის დაპირეკვა ხედზე:

    • შეგიძლიათ დაპირეკოთ UITapGestureRecognizer დაჭერის ჟესტი იმ UIView-ზე, რომელიც დაკავშირებულია ფენასთან:
    • ჟესტის დამუშავებაში მიიღეთ შეხების ადგილმდებარეობა ხედთან მიმართებაში:
    • შემდეგ გამოიყენეთ კოორდინატების გადაყვანის მეთოდი (მოსაზღვრე 2), რათა შეამოწმოთ, არის თუ არა წერტილი შეხების ადგილზე საჭირო ფენაში ან მის ქვედა ფენებში:
  4. შექმენით UIView თითოეული ინტერაქტიული ფენისთვის:

    • თუ გაქვთ ფენები, რომლებიც უნდა იყოს ინტერაქტიული, ყველაზე მარტივი გზა — შექმნათ შესაბამისი UIView თითოეულ ასეთ ფენაზე:
    • განლაგება და ზომის დაყენება ფენის შესაბამისად:
    • დაპირეკეთ ჟესტების დამუშავების მექანიზმები (UITapGestureRecognizer) ან გადაწერეთ შეხების მოვლენის მეთოდები (touchesBegan, touchesEnded და ა.შ.) ამ ხედზე:
    • ეს ყველაზე იდიომატური მეთოდია მომხმარებლის შეყვანის დამუშავებისთვის UIKit-ში, რადგან UIView-ი სპეციალურად ამისთვის არის შექმნილი:

მაგალითი hitTest-ის გამოყენება UIView-ში:

// პერსონალურ `UIView`-ში
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // გადაყვანა წერტილიდან ქვედა ფენაში
    let pointInLayer = mySublayer.convert(point, from: layer!)
    
    // შემოწმება, არის თუ არა წერტილი ფენის საზღვრებში
    if mySublayer.contains(pointInLayer) {
        // თუ წერტილი ფენაშია, შეგიძლიათ დაბრუნდეთ თქვენ ან სხვა ხედს,
        // ან განახორციელოთ საჭირო მოქმედებები:
        print("დაჭერით mySublayer-ზე")
        // შეგიძლიათ დაბრუნდეთ nil, თუ არ გსურთ, რომ ეს ხედი გააგრძელოს დამუშავება,
        // ან `super.hitTest(point, with: event)` თუ გსურთ სტანდარტული ქცევის შენარჩუნება
    }
    
    // ნებართვა სტანდარტულ `hitTest`-ს სხვა შემთხვევების დამუშავება
    return super.hitTest(point, with: event)
}

convert-ის გამოყენების მაგალითი ჟესტის დამუშავებაში:

// `UITapGestureRecognizer`-ით დაკავშირებულ `UIView`-ში
@objc func handleTap(_ sender: UITapGestureRecognizer) {
    let tapLocationInView = sender.location(in: self)
    
    // გადაყვანა შეხების წერტილიდან ფენის ქვედა ფენაში
    let tapLocationInSublayer = mySublayer.convert(tapLocationInView, from: layer!)
    
    // შემოწმება, არის თუ არა წერტილი ფენის საზღვრებში
    if mySublayer.contains(tapLocationInSublayer) {
        print("mySublayer-ზე დაჭერა")
        // განახორციელეთ მოქმედებები, რომლებიც დაკავშირებულია ფენის დაჭერასთან
    }
}