Sürükleme için kendiniz uygulayabileceğiniz açık yerleştirme kuralları gerekiyorsa SwiftUI Canvas'ı seçin. Şekillerin fizik kurallarıyla birbirini itmesi, sekmesi veya hareket etmeyi sürdürmesi gerekiyorsa SpriteKit'i seçin. Önce, sürüklenen bir şekil başka bir şekille karşılaştığında ne olacağına karar verin.

Bu kılavuz tek bir görevi ele alıyor: kullanıcıların uygulamanın kendi çalışma alanında sürüklediği, bellekte tutulan sentetik daireler veya dikdörtgenler içeren bir Mac uygulaması için etkileşim mimarisini seçmek. Karar; çarpışma davranışına, girdi yönlendirmesine ve her şeklin konumunu hangi bileşenin denetlediğine bağlıdır.

İki şekil karşılaştığında ne olmalı?

“Çarpışma tepkisi” birkaç farklı gereksinimi ifade edebilir. Örtüşmeyi vurgulamak, geçersiz bir konumu reddetmek ve iki nesnenin sekmesini sağlamak farklı mekanizmalar gerektirir. Apple, dokunmakta olan gövdeleri bildiren SpriteKit temaslarını, fiziksel tepkiyi hesaplayıp dürtüler uygulayan çarpışmalardan açıkça ayırır. Çarpışmalar ve Temaslar Hakkında

İstenen davranış Uygulamaya başlamak için pratik seçenek Sizin üstleneceğiniz sorumluluklar
İşaretçi şekli serbestçe yerleştirirken örtüşmeyi vurgulamak Özel geometri testleriyle Canvas Seçim, örtüşme algılama ve görsel geri bildirim
Bir şekli ilk engele kadar durdurmak Özel hareket kısıtlamalarıyla Canvas Hareket yolunu sınamak ve kabul edilen konumu belirlemek
Komşu şekilleri itmek, durulmalarına veya sekmelerine izin vermek SpriteKit Fizik yapılandırması ve sürükleme denetleyicisi
Her öğeye sıradan SwiftUI denetimleri ve hareketleri vermek Ayrı SwiftUI görünümleri Uygulamaya özgü örtüşme veya hareket kuralları

Bunlar, belgelenmiş özelliklerden çıkarılan mimari önerilerdir; Apple'ın performans eşikleri değildir. Az sayıda şekil olması Canvas'ı kendiliğinden daha uygun kılmaz; çok sayıda şekil olması da SpriteKit'i zorunlu kılmaz. Önce davranışı seçin, ardından temsili öğelerle uygulamanın performansını ölçün.

Ayrıca yararlı bir etkileşim kısıtı vardır: işaretçiyi tam olarak izlemek ile katı bir örtüşmeme kuralı çatışabilir. İşaretçi dolu bir konumdan geçerse uygulama, öğenin örtüşmesine izin vermeli, onu işaretçinin gerisinde durdurmalı veya diğer öğeleri hareket ettirmelidir. Görüntüleyiciyi seçmeden önce bu tercihi belirleyin.

Canvas ne sağlar, neleri sizin oluşturmanız gerekir?

Canvas, grafik bağlamı üzerinden anlık çizim sağlar. Daireleri, yolları ve sembolleri bağımsız etkileşimli öğelere dönüştürmez. Apple ayrıca Canvas'ın tek tek çizilen öğeler, görünüm olarak sağlanan semboller de dahil, için erişilebilirlik desteği sunmadığını belirtir. Bu nedenle Canvas'a eklenen bir hareket, kullanıcının hangi öğeyi seçtiğini belirlemek için uygulama mantığı gerektirir. Canvas

Açık yerleştirme kuralları olan bir düzenleyicide şekilleri bir modelde tutun ve çizimi bu modelin bir yansıması olarak ele alın. Her öğe bir tanımlayıcı, merkez, boyutlar ve çizim sırası içerebilir. Swift'in kılavuzu, sıradan veriler için varsayılan olarak yapıları; paylaşılan kimlik veya çerçeve kalıtımı gerektiğinde sınıfları önerir. Değer türündeki bir öğe modeli ile SpriteKit sahne alt sınıfı farklı amaçlara hizmet eder. Yapılar ve Sınıflar Arasında Seçim Yapma

Canvas sürüklemesi şu sırayla ilerleyebilir:

  1. Hareket başladığında, ilk eşleşen öğeyi seçmek için başlangıç işaretçi konumunu öğeler üzerinde çizim sırasının tersine doğru sınayın.
  2. Seçilen tanımlayıcıyı ve özgün merkezi hareket boyunca saklayın.
  3. Önerilen her merkezi, bu özgün merkeze hareketin toplam ötelemesini ekleyerek hesaplayın.
  4. Kabul edilen merkezi bulmak için çalışma alanı sınırlarını ve çarpışma kurallarını uygulayın.
  5. Modeli güncelleyin; Canvas'ın modelden yeniden çizmesini sağlayın.
  6. Hareket sona erdiğinde seçimi temizleyin ve kesintiye uğrayan etkileşimler için temizleme davranışını tanımlayın.

Toplam hareket ile artımlı hareket arasındaki fark önemlidir. SwiftUI, translation değerini hareketin başlangıcından itibaren olan hareket olarak tanımlar. Bu toplamı güncellenmiş bir merkeze her seferinde eklemek, hareketin gereğinden fazla birikmesine yol açar. Her seferinde saklanan başlangıç merkezini kullanın. SwiftUI, hareket değeri üzerinden startLocation, location ve translation değerlerini sunar ve hareketin koordinat alanını belirtmenize olanak tanır. DragGesture.Value, DragGesture

Sürükleme boyunca seçimi sabit tutun. Her işaretçi güncellemesinde başlangıçtaki seçme işlemini yinelemek, işaretçi başka bir şeklin üzerinden geçerken seçilen öğeyi değiştirebilir. Aynı şekilde, işaretçi ile merkez arasındaki başlangıç uzaklığını korumak, şeklin işaretçinin altına gelecek şekilde aniden sıçramasını önler. Bunlar, Canvas'ın kendiliğinden sağladığı davranışlar değil, uygulama tasarımı kurallarıdır.

İşlenmiş bir örnek: örtüşme algılama ile hareketi engelleme

Yarıçapı 20 nokta olan iki örnek daire düşünün. A dairesi (100, 100) konumunda başlıyor, sabit B dairesi ise (200, 100) konumunda. Kullanıcı, A'nın merkezini (190, 100) konumuna getirmek istiyor. Merkezler arasındaki uzaklık 10 nokta, yarıçapların toplamı ise 40 nokta olurdu. Bu aday konum örtüşmeye neden olur.

Örtüşme göstergesi için bu konumu kabul edip çizimi değiştirin. Yatay sürüklemeyi engellemek için ilk temas konumu (160, 100) olur: merkezler arasındaki uzaklık bu noktada 40 noktadır. Bu hesaplama B'nin sabit kaldığını, iki dairenin boyutlarının değişmediğini ve A'nın yatay bir yol izlediğini varsayar.

Şimdi tek bir işaretçi güncellemesinin (260, 100) istediğini varsayalım. Yalnızca bu son noktayı sınamak örtüşme olmadığını gösterir; oysa hareket yolu B'nin içinden geçer. Engellenen sürükleme davranışını uygulamak için yol üzerindeki kesişmeyi test etmek veya aradaki yolu sınayan başka bir açık yöntem kullanmak gerekir. Yalnızca örtüşen son noktaları reddetmek, “ilk engelde dur” davranışını uygulamaz.

Bu örnek, çarpışma tepkisini açıkça tanımlamanın başlıca nedenini gösterir. Birkaç son nokta geometri testi, örtüşmeyi vurgulama özelliğini tamamlamaya yetebilir. Engellerin çevresinden kaymayı, eşzamanlı temasları veya komşu öğelerin hareket etmesini desteklemek, özel çözücüyü büyük ölçüde kapsamlı hâle getirir. Canvas çizim seçeneği olmaya devam eder, ancak bu ek davranışların sorumluluğu uygulamanızdadır.

SpriteKit ne zaman daha uygun olur?

Çarpışma tepkisinin simülasyondan kaynaklanmasını istediğinizde SpriteKit cazip hâle gelir. Bir düğüme SKPhysicsBody eklemek yerçekimi, sürtünme ve çarpışmalarla ilgili hesaplamaları mümkün kılar; ardından simülasyon düğümlerin konumlarını ve yönelimlerini günceller. Nesneler için hacim gövdelerini, sınırlar içinse kenar gövdelerini destekler. SKPhysicsBody

İlk prototip için aralıklı iki daire ve dikdörtgen bir çalışma alanı sınırı kullanın. Dairelere eşleşen dairesel gövdeler verin, masa üstü tarzı bir çalışma alanında yerçekimini devre dışı bırakın ve dönüşün etkileşime katkısı olup olmadığına karar verin. Sürtünme, esneklik ve sönümleme değerlerini varsayılanlarına güvenmek yerine bilinçli şekilde yapılandırın. Bu özellikler, fiziksel davranışın farklı yönlerini belirler. SKPhysicsBody

Apple'ın SwiftUI görünümü SpriteView ile sahneyi doğrudan SwiftUI içinde barındırabilirsiniz; belgelerde SpriteKit sahnesi işleyen bir SwiftUI görünümü olarak tanımlanır. Belgelenen Mac desteği macOS 11 ile başlar; Canvas desteği ise macOS 12'de başlar. Etkileşim davranışı başlıca ölçüt olsa da dağıtım hedefleri karara dahildir. SpriteView, Canvas

Çarpışma tepkisini bildirimlerden ayrı yapılandırın

Şekillerinize ve sınırınıza kategoriler atayın, ardından iki etkileşim maskesini açıkça yapılandırın:

  • categoryBitMask, bir gövdenin ait olduğu kategorileri belirler.
  • collisionBitMask, bu gövdeyi fiziksel olarak etkileyebilecek kategorileri seçer.
  • contactTestBitMask, seçilen kategoriler için temas bildirimleri ister.

Çarpışma maskeleri her gövde için bağımsız değerlendirilir. İki dinamik şeklin karşılıklı tepki vermesi için her iki gövdeyi de diğerinin kategorisine tepki verecek şekilde yapılandırın. Temas bildirimi için farklı bir kural geçerlidir: kategorinin ve temas maskesinin herhangi bir yöndeki eşleşmesi bildirim oluşturabilir. Yalnızca bildirimleri etkinleştirmek, fiziksel engellemeyi yapılandırmaz. collisionBitMask, contactTestBitMask

Gövde fiziksel olarak tepki verdiği hâlde geri çağırma gelmiyorsa temas maskesini ve fizik dünyasının temas temsilcisini denetleyin. Şekiller birbirinin içinden geçerken geri çağırmalar geliyorsa çarpışma maskelerini ve hareket denetleyicisini inceleyin. Bu denetimler, bildirim yapılandırmasını gerçek hareket sorunundan ayırmaya yardımcı olur.

Kullanıcı sürüklerken konumu kim denetler?

SpriteKit sürüklemesi açık bir denetleyici gerektirir. Fizik motoru tek başına işaretçiyi izleyen bir etkileşim değildir. Daha önce belirlenen davranışa göre doğrudan yerleştirme ile simülasyonun yönettiği hareket arasında seçim yapın.

Doğrudan yerleştirmede uygulama kodu, sürüklenen düğümün konumunu atar. İşaretçinin öğeyi tam olarak yerleştirmesi gerektiğinde bu uygundur, ancak ardışık konumlar arasındaki yolu kendiliğinden fizik kurallarına göre çözmez. isDynamic değerini kapatmak gövdenin kuvvetleri ve dürtüleri yok saymasını sağlar; sürükleme çözücüsü oluşturmaz. Bu özelliği geçici olarak değiştiriyorsanız ne zaman geri yükleneceğini ve bırakıldığında hareketin korunup korunmayacağını tanımlayın. isDynamic

Simülasyonun yönettiği sürüklemede işaretçinin konumunu hedef olarak saklayın ve dinamik gövdeyi bu hedefe yönlendirmek için kuvvetler veya yay tabanlı bir denetleyici kullanın. Böylece simülasyon, gövde hareket ederken temasları çözebilir. Bunun karşılığında başka bir nesne hareketi engellediğinde işaretçiyi bilinçli olarak gecikmeli ya da ondan uzakta izler. SpriteKit kuvvet uygulamayı destekler; SKPhysicsJointSpring iki fizik gövdesini yay davranışıyla birbirine bağlar. Bunlar, uygulamaya özel ayar gerektiren yapı taşlarıdır. SKPhysicsBody, SKPhysicsJointSpring

Fizik motorunun aynı konumu bağımsız olarak denetlemesini beklerken işaretçi konumlarını sürekli atamaktan kaçının. SpriteKit'in belgelenmiş kare sırası; uygulama güncellemelerini, eylemleri, fiziği ve sonraki geri çağırmaları ayrı aşamalarda çalıştırır. Yararlı bir sahiplik kuralı, girdinin sürükleme hedefini güncellemesi, sahne mantığının denetleyiciyi uygulaması ve fiziğin gövdenin ortaya çıkan konumunu üretmesidir. Kare Döngüsü Olaylarına Yanıt Verme

Temas geri çağırmalarının belgelenmiş bir sınırı da vardır. Apple, bunların fizik simülasyonu adımında çalıştığını; bu sırada fizik dünyasını değiştirmenin desteklenmediğini ve simüle edilen gövdelerde yapılan değişikliklerin tanımsız davranışa yol açacağını belirtir. Bekleyen işi geri çağırmada kaydedin ve Apple'ın bayrak koyup güncelleme modelini izleyerek fizik değişikliklerini sonraki bir güncellemede uygulayın. SKPhysicsContactDelegate

macOS girdisi çerçeve sınırlarını nasıl aşmalı?

Çalışma alanı için tek bir girdi sahibi seçin. Canvas uygulaması etkileşim yüzeyine bir SwiftUI DragGesture ekleyebilir. Özel bir AppKit yüzeyi yanıtlayıcı olaylarını işleyebilir; mouseDragged(with:), sol fare düğmesi basılıyken gerçekleşen hareketi alır. Üst üste bindirilmiş bir SwiftUI hareketinin ve AppKit işleyicisinin aynı seçili öğeyi birbirinden bağımsız olarak hareket ettirmesine izin vermeyin. DragGesture, mouseDragged(with:)

AppKit ile SpriteKit arasında köprü kurarken her sınırda koordinatları dönüştürün. NSEvent.locationInWindow normalde ilişkili pencerenin temel koordinat sisteminde ifade edilir. Bu noktayı barındıran görünümün koordinatlarına, ardından görünüm koordinatlarından sahne koordinatlarına dönüştürün. Apple, son adım için convertPoint(fromView:) sağlar ve çağrılmadan önce sahnenin sunulmuş olmasını şart koşar. Bir düğümün konumu üst öğesinin koordinat sisteminde ifade edilir; iç içe düğümlerde ek bir dönüşüm gerekebilir. locationInWindow, convertPoint(fromView:), position

Basit SwiftUI barındırma için SpriteView kullanın. Özel bir AppKit görünümüne ihtiyacınız varsa NSViewRepresentable oluşturma, güncelleme, koordinasyon ve kaldırma olanakları sağlar. Temsil edilen görünümün yerleşiminden SwiftUI'ı sorumlu tutun: Apple, yönetilen çerçevesini veya sınırlarını kendiniz atamanız konusunda açıkça uyarır. NSViewRepresentable

SwiftUI görünüm içeriğini her yeniden hesapladığında yeni bir sahne oluşturmak yerine sahneyi kararlı bir sahip içinde tutun. Canvas için de öğe modelini benzer şekilde saklayın. SwiftUI'ın model verisi belgeleri, yönetilen durumun görünüm yeniden oluşturulurken bir örneği nasıl koruduğunu açıklar; Observation yaklaşımı macOS 14 veya üstünü gerektirir. Sahne komutlarını ve model anlık görüntülerini bilinçli veri aktarımları olarak ele alın; böylece iki değiştirilebilir kopya konumları belirlemek için yarışmaz. Uygulamanızda model verilerini yönetme

Bu yaklaşımlardan birine karar vermeden önce neleri sınamalısınız?

Görsel ayrıntıları eklemeden önce zor etkileşimleri sınamak için küçük, sentetik bir çalışma alanı kullanın:

  1. Bir şeklin kenarına yakın tutup başlangıç uzaklığının korunduğunu doğrulayın.
  2. Başka bir öğeye doğru yavaşça sürükleyin, ardından üzerinden tek ve büyük bir işaretçi hareketiyle geçmeyi deneyin.
  3. Köşeye, yan yana duran iki şekle doğru sürükleyin.
  4. Başka bir öğeye dokunurken bırakın ve amaçlanan durulma davranışını denetleyin.
  5. Çalışma alanını yeniden boyutlandırın; seçimi, sınırları ve koordinat dönüşümünü doğrulayın.
  6. Çevredeki SwiftUI içeriğini yeniden oluşturun ve öğe konumlarının korunduğunu doğrulayın.
  7. Sürüklemeyi yarıda kesin; seçimin ve geçici fizik ayarlarının temizlendiğini doğrulayın.

SpriteKit'te gövde geometrisinin amaçlanan çarpışma alanına uyduğunu denetlerken SKView.showsPhysics özelliğini etkinleştirin. Hızlı hareket eden küçük gövdeler için usesPreciseCollisionDetection özelliğini değerlendirin; Apple, bu özelliğin daha yüksek hesaplama maliyetine sahip olduğunu ve sıradan kare tabanlı denetimlerin kaçırabileceği çarpışmaları algıladığını belirtir. Bu özellik tutarlı bir sürükleme denetleyicisinin yerini almamalıdır. SKView, usesPreciseCollisionDetection

Yerleştirme kurallarınız açık, sınırlı ve doğrudan ifade edilebilir kalıyorsa Canvas'ı seçin. Şekiller arasındaki fiziksel etkileşim görevin bir parçasıysa SpriteKit'i seçin. Her iki uygulamada da güvenilir bir masaüstü sürüklemesi; tek bir seçili öğeyle, açık koordinat dönüşümleriyle ve her konum güncellemesinden sorumlu tek bir bileşenle başlar.

Kaynaklar