2015-09-29 42 views
5

Devo essere in grado di interagire con una rappresentazione di un cilindro che contiene molte parti differenti. Quando gli utenti toccano sopra dei rettangoli piccoli, ho bisogno di visualizzare un popover relativo al pezzo specifico (modulo).Interagire con la figura complessa in iOS

L'immagine successiva mostra un approccio 3D realistico. Ma, ripeto, ho bisogno di risolvere il problema, il 3d non è richiesto (sarebbe davvero bello però). Una rappresentazione che soddisfi i bisogni funzionali sarà sufficiente.

Le informazioni circa le parti per fare il disegno proviene da un API (dimensione, posizione, ecc)

enter image description here

non ho bisogno di essere realistico davvero. La più semplice aproximation sarebbe mostrare un cilindro in una rappresentazione 2D, come un rettangolo formato da piccoli rettangoli intercambiabili.

Quindi, come ho detto, penso che ci sono (come la vedo io) due approcci opposti: realistica o semplificato

C'è un modo per ottenere una bella soluzione nel mezzo? Quali librerie, componenti, framework dovrei esaminare?

La mia ricerca mi ha portato a SceneKit, ma non so ancora se riuscirò a interagire con esso. L'interazione è una parte molto importante in quanto è necessario visualizzare un popover quando l'utente tocca un piccolo rettangolo sul cilindro.

Grazie

+0

cosa intendi esattamente per "l'interazione è una parte molto importante" quando dici che anche una versione 2D statica è ok? – mnuages

+0

Devo visualizzare un popover quando l'utente tocca un piccolo rettangolo del cilindro – tomasbarrios

+0

Questa è una rappresentazione corretta della versione "semplice": [Cylinder Image] (http://www.polynaut.net/cylinder.jpg) ? Tutto ciò può essere fatto usando UIKit ottenendo la posizione del tocco dell'utente e usando un popover con i dati corrispondenti. – George

risposta

1

Teoricamente, facendo questo in scena Kit con uno o SpriteKit UIKit Popovers è l'ideale.

Tuttavia Scene Kit (e Sprite Kit) sembrano essere in uno stato di flusso in cui nessuno di Apple sta comunicando con gli utenti circa la serie di problemi che la gente sta avendo con entrambi. Da Sprite Kit relativamente stabile e performante in iOS 8.4 a molte prestazioni perse in iOS 9 sembra comune. Scene Kit semplicemente non sembra finito, e la documentazione e la comunità sono quasi inesistenti come risultato.

Detto questo ... la teoria è questa:

ID materiale sono ciò che è utilizzato in applicazioni 3D tradizionali per definire le aree di un oggetto che hanno diversi materiali. In qualche modo questi Material ID sono chiamati "elementi" in SceneKit. Non sono stato in grado di trovare molto di più su questo.

Dovrebbe essere possibile rilevare "l'elemento" che si trova al di sotto di un tocco su un oggetto e rispondere di conseguenza. Dovresti anche essere in grado di cambiare lo stato/la natura del materiale su quell'elemento per indicare che è il selezionato al momento.

Quando si desidera un cilindro liscio e ben arrotondato come nell'esempio, iniziare con un cilindro composto da solo un numero sufficiente di segmenti per descrivere/definire gli ID materiali necessari per le sezioni "rettangolari" da toccare.

Successivamente è possibile aggiungere un'operazione di livellamento al cilindro per arrotondarlo, e tutta la geometria di arrotondamento extra in ogni quadrante dell'ID materiale univoco deve essere reattiva, indipendentemente da come si aggiungono questi dettagli extra per facilitare la presentazione del cilindro.

1

Idea per la versione "semplificata":

se this representation è okey, è possibile utilizzare un UICollectionView. Ogni cella può avere una dimensione definita grazie

collectionView:layout:sizeForItemAtIndexPath: 

Poi ogni cella della raccolta potrebbe essere un piccolo rettangolo che rappresenta una parte tangibile del cilindro.

e utilizzando

collectionView:(UICollectionView *)collectionView 
    didSelectItemAtIndexPath:(NSIndexPath *)indexPath 

Per ottenere il tocco.

Questo vi aiuterà a visualizzare il popover al posto giusto:

CGRect rect = [collectionView layoutAttributesForItemAtIndexPath:indexPath].frame; 

Infine, si può scegliere il popover appropriata (se l'applicazione deve lavorare su iPhone) qui: https://www.cocoacontrols.com/search?q=popover

Non perfetto, ma penso che sia efficiente!

+0

La visualizzazione del cilindro da una vista laterale piatta non comunica un cilindro all'utente. –

+0

"Sì, sarebbe una rappresentazione corretta, tuttavia le forme all'interno del cilindro potrebbero essere un po 'più complesse." - tomasbarrios Puoi consultare il commento;) – Alban

2

Non è necessario alcun quadro speciale per ottenere un'interazione come questa. Questo effetto può essere ottenuto con lo standard UIKit e UIView e con una piccola trigonometria. È possibile disegnare esattamente l'immagine di esempio utilizzando la matematica 2D e il disegno. La mia risposta non è una formula esatta, ma implica pensare a come sono definite le forme e suddividere il problema in passi gestibili.

Un cilindro può essere definito da due cerchi sfalsati che rappresentano i pezzi terminali, collegati ai loro raggi. Userò una proiezione ortogonale che significa che il cilindro non appare più piccolo man mano che la profondità si estende sullo sfondo (ma potresti adattarti alla prospettiva se necessario). Puoi disegnarlo con CoreGraphics in un UIView drawRect.

Una porzione quadrata rappresenta un angolo del cerchio, sfalsato di una quantità inferiore alla lunghezza del cilindro, ma nella stessa direzione, come nel seguente diagramma (mi dispiace per il disegno impreciso).

enter image description here

Questo angolo piazza ci interessa è l'area delineata nella solido rosso, al di fuori del raggio del primo cerchio, e dentro il raggio del secondo cerchio immaginario (che è appena sfalsato dal primo cerchio di qualsiasi lunghezza vuoi la fetta).

Per disegnare quest'area è sufficiente disegnare un tracciato del contorno di ciascun arco e collegare i punti finali.

Per verificare se un tocco si trova all'interno di una di queste fette quadrate:

  1. Controllare se il punto di contatto è tra l'angolo a dall'origine a a.
  2. Verificare se il punto di contatto si trova al di fuori del raggio del cerchio interno.
  3. Controllare se il punto di contatto si trova all'interno del raggio del cerchio esterno. (Nota cosa significa se i cerchi sono più di un raggio a parte.

Per trovare un punto per visualizzare il popover, è possibile calcolare la media dei punti finali sulla sezione o trovare l'angolo medio tra i due bordi e l'offset di metà della distanza.

0

Sì, SceneKit.

Quando l'utente esegue un evento tattile, ciò significa che si conoscono le coordinate 2D sullo schermo, quindi l'unica decisione è quella di visualizzare una vista o meno, anche se non esiste un modello 3D.

In primo luogo, possiamo dividere logicamente il requisito in due parti, determinare il segmento toccante, mostrare il giusto "colore" in ciascun segmento.

Penso che l'uso del modello 3D sia per determinare quale pezzo di dati mostrare nel tuo caso se non ti sbaglio. In tal caso, il metodo di hit hit di SCNView farà la maggior parte del lavoro per te. Quello che dovresti fare è eseguire un hit test, eliminare il nodo di successo e la coordinata 3D locale di questo nodo, puoi quindi calcolare quale segmento viene colpito da questo tocco e prendere la decisione.

Ora come disegnare la superficie del cilindro sarebbe l'unica domanda lasciata, giusto? Ci sono vari modi per fare, per esempio semplicemente dipingere ogni immagine che ti serve e programmaticamente e collegarla al materiale del cilindro o avere i tuoi file immagine su disco e utilizzarli come materiale per il cilindro ...

Penso che il problema sarebbe essere sostanzialmente risolto.