UIScrollView Tutorial – Scrollen und Zoomen

Einleitung

Wenn man sehr viele oder sehr große Informationen, wie beispielsweise ein hochauflösendes Bild, auf dem iPhone darstellen will, benötigt man schnell mal mehr Platz, als einem das Display bietet. Deswegen gibt es ein Object namens Scroll View. Ein Scroll View ist wie ein normaler View, nur dass man, wie auf einer Internetseite, vertikal und/oder horizontal scrollen kann. Außerdem bieten Scroll Views die Möglichkeit, an ein Bild heran oder heraus zu zoomen und vieles mehr.

Hier also eine kleine Übersicht, was du in diesem Tutorial lernen wirst:

  • Implementierung eines Scroll Views
  • Zoomen in einem Scroll View
  • Benutzen eines Image Views

1. Die App

Die App wird eine einzelne Scene mit einem Scroll View sein. Dieser wird ein Bild mit den Maßen 320×900 enthalten, also zu groß für das Display. Um das Bild trotzdem anzeigen zu können, wird man Scrollen und Zoomen können. Los geht’s.

2. Das Interface

Öffne Xcode und klicke im Startup-Fenster auf “Create a new Xcode project”. Für das Tutorial eignet sich am besten das Single View Application-Template. Bei Product Name kannst du bspw. “UIScrollViewTutorial” eingeben. Die restlichen Projekt-Optionen sollten so wie immer sein:

Gib schließlich noch den Speicherort an und klicke auf Create.

Öffne gleich zuerst die Datei “MainStoryboard.storyboard”.
Zu Beginn benötigen wir das eigentliche Scroll View-Object. Suche es in der Library und ziehe den Scroll View so in das Fenster, dass er seine volle Größe annimmt.

Damit wir ein Bild in unseren Scroll View einfügen können, benötigen wir einen Image View. Den findest Du in der Library in der Nähe des Scroll Views. Ziehe ihn auf den Scroll View,  sodass er den ganzen View bedeckt.

Achte darauf, dass er innerhalb des Scroll Views liegt. Das kannst du im Document Outline links im Storyboard Editor überprüfen:

Bis jetzt ist der Image View genauso groß wie das Display. Da wir aber wissen, dass unser Bild die Maße 320×900 haben wird, können wir den Image View gleich auf diese Größe einstellen. Wähle ihn aus, indem Du im Document Outlet auf ihn klickst, und lass ihn dir im Size inspector anzeigen (das ist der 2. Button von rechts). Dort änderst Du den Wert über Height auf 900. Die Breite stimmt bereits:

Jetzt müssen wir den Image View noch so hinschieben, dass seine obere Kante auf der oberen Kante des Scroll Views liegt.

So befindet sich nämlich der obere Teil des Bildes auch im oberen Teil des Scroll Views.

Nun fehlt nur noch das Bild. Du kannst ein eigenes benutzen oder einfach das Beispielbild downloaden: Image.png. Man merkt, dass ich ein wahrer Grafik-Virtuose bin :-) .

Nachdem Du es geladen hast, ziehe es einfach vom Download-Folder in den Ordner ”Supporting Files” im Project navigator. Wenn Du die Maustaste loslässt, erscheint ein Dialog. Es ist wichtig, dass dort der Haken bei “Copy items into destination group’s Folder (if needed)” gesetzt ist. Ansonsten würde nur eine Referenz der Datei erstellt werden, was später eventuell zu Problemen führt:

Klicke auf Finish um den Dialog zu schließen.

Jetzt, da das Bild importiert ist, ist es ganz einfach dieses in den Image View zu bekommen. Stelle sicher, dass der Image View angewählt ist und öffne den Attributes inspector. Gleich die erste Eigenschaft heißt Image. Gib dort den Namen des Bildes ein (mit Dateiendung).

Daraufhin erscheint das Bild auch schon im View.

Wenn wir die App nun einfach mal ausführen und versuchen mit einem Mauswisch zu scrollen, stellen wir fest, dass es nicht geht. Das liegt daran, dass der Scroll View nicht weiß, wie groß sein Inhalt ist, also wie weit er scrollen können muss. Um ihm das mitzuteilen, müssen wir ein paar Zeilen Code schreiben.

3. Der Scroll View im Code

Zuerst bleiben wir aber noch im Storyboard-Editor. Wir benötigen nämlich das Outlet des Scroll Views, damit wir mit ihm im Code arbeiten können.

Teile deswegen den Editor Bereich in zwei Teile (mit dem mittleren Button von Editor in der Tool Bar) und vergewissere dich, dass im rechten Bereich die Datei “ViewController.h” angezeigt wird. Dann klicke mit gedrückter ctrl-Taste auf den Scroll View im Document Outline und ziehst den blauene Faden unter die @interface-Zeile im Code-Editor:

Nenne das Outlet “scrollView” und klicke auf Connect.

Stelle die Ansicht wieder auf Standard editor um und öffne die Datei “ViewController.m”.
Da wir die Größe des Inhalts des Scroll Views am besten noch vor dem Erscheinen des Views einstellen, bearbeiten wir die Methode viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    scrollView.contentSize = CGSizeMake(320, 900);
}

Hinweis: Die Methode viewDidLoad wird aufgerufen, wenn der View aus dem Storyboard geladen wurde. Das ist ein günstiger Zeitpunkt, um Änderungen am View vorzunehmen.

Es ist leicht verständlich, was hier passiert. Wir setzen die contentSize, also die Größe des Inhalts, des Scroll Views auf die ungefähren Ausmaße des Image Views.

Führe die App erneut aus, um zu sehen, ob man nun scrollen kann. Wenn man jetzt mit gedrückter Maustaste die Maus bewegt, wird gescrollt. Jetzt fehlt nur noch das Zoomen.

4. Zoomen

Die Implementierung der Zoom-Funktion ist recht simpel. Wir benötigen allerdings das UIScrollViewDelegate. Dieses enthält, genauso wie bspw. das UITextFieldDelegate, zusätzliche Methoden. Eine davon benötigen wir.

Um das UIScrollViewDelegate einzubinden, öffne die Datei “ViewController.h” und ändere die @interface-Zeile wie folgt ab:

@interface ViewController : UIViewController <UIScrollViewDelegate>

Wie bei jedem Delegate müssen wir nur den Namen in spitzen Klammern hinter die Klasse schreiben. Und wie bei jedem Delegate müssen wir es noch mit einem Object im Storyboard-Editor verbinden, dem Scroll View.

Öffne also wieder die Datei “MainStoryboard.storyboard” und wähle den Scroll View aus. Öffne dann den Connections inspector und ziehe den blauen Faden von delegate auf das View Controller-Object im Document Outline.

Das Delegate wird automatisch verbunden und jetzt weiß Xcode, zu welchem Object im Storyboard das Delegate gehört.

Wir bleiben gleich im Storyboard-Editor, um eine weitere Einstellung vorzunehmen. Und zwar können wir ganz einfach den minimalen und maximalen Zoom im Scroll View einstellen, welche beide standardmäßig auf 1 stehen.

Öffne also den Attributes inspector und ändere die Werte bei Zoom Min bzw. Max auf -5 und 5.

Nun müssen wir noch ein weiteres Outlet erstellen, welches wir später benötigen werden. Das Outlet des Image Views.

Teile den Editor-Bereich wieder in zwei Teile, indem Du die Ansicht auf Assistant editor (wieder der mittlere Editor-Button in der Tool Bar) einstellst, und ziehe, wie beim Scroll View, den blauen Faden vom Image View in den Code-Editor unter das erste Outlet.

Gib dem Outlet den Namen image und klicke auf Connect. Hier sind wir fertig; stelle also wieder auf Standard editor um.

Jetzt fehlt nur noch der letzte Schritt: Die Zoom-Methode. Öffne die Datei “ViewController.m” und füge folgende Methode unter der geschweiften Klammer von viewDidLoad ein:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.image;
}

In dieser Methode legen wir fest, an welches Object herangezoomt wird. Dazu geben wir das Outlet des Image Views mit der return-Anweisung zurück.

Hinweis: return …; gibt ein Objekt an diejenige Instanz “zurück”, welche die Methode aufruft. Welcher Art das zurückgegebene Objekt sein muss, steht in den runden Klammen, vorne im Funktionskopf; also bei dieser Methode “UIView”. Da ein UIImageView eine Subclass also eine “Unterkategorie”, des UIViews ist, können wir auch das image-Outlet zurückgeben. Methoden bei denen void in den Klammern steht, benötigen keine return-Anweisung.

Jetzt ist unsere App fertig. Führe sie aus, um zu sehen, ob alles funktioniert.
Jetzt braucht es nur noch ein letzte Hürde zu bewältigen: Wie zoomt man im Simulator? Nun, da einem nur ein Mauszeiger zur Verfügung steht, man zum Zoomen auf dem iPhone aber zwei Finger benötigt, hat sich Apple etwas einfallen lassen. Wenn man im iOS Simulator die alt-Taste gedrückt hält, erscheinen zwei Punkte mit denen man zoomen kann.

(Ich kann leider bei gedrückter Alt-Taste kein Bildschrimfoto aufnehmen, deshalb habe ich versucht es nachzumachen)

5. Schluss

Das fertige Xcode-Projekt gibt’s wie immer zum Downloaden: UIScrollView Tutorial – Scrollen und Zoomen

Dies ist ein Tutorial-Wunsch eines Lesers. Falls Du selbst eines vorschlagen möchtest, kannst du einfach ein Kommentar hinterlassen oder mich kontaktieren. Allerdings kommen ziemlich viele Vorschläge rein, weshalb es immer ein wenig dauern kann bis das Tutorial schließlich rauskommt.

Wenn du noch irgendwelche Fragen oder Kritikpunkte hast, gib mir einfach über die Kommentarfunktion Bescheid. Möchtest Du keine weiteren Tutorials verpassen, dann abonniere einfach den Blog RSS oder folge mir auf Twitter. Wenn dir das Tutorial gefallen hat, würde ich mich freuen, wenn du es verbreitest oder mit anderen teilst.

This entry was posted in iPhone SDK, Tutorial and tagged , , , , . Bookmark the permalink.

18 Responses to UIScrollView Tutorial – Scrollen und Zoomen

  1. hiddenseise says:

    Hallo,

    Weisst du wie ich machen kann, dass man nur auf einem bestimmten Bereich des Displays scrollen kann? Also ich will zum Beispiel dass man nur am oberen Rand scrollen kann und wenn man den Bildschirm unten berührt sollte nichts passieren…
    Gibt es dazu einen Befehl?

    • Felix says:

      Hallo,

      ich hätte die Idee einfach einen normalen UIView für über die untere Hälfte des Scroll Views zu legen und diesen dann durchsichtig zu machen. Dann kann nur noch oben gescrollt werden.

      Viele Grüße
      Felix

  2. Marcel says:

    Hallo,
    ich bin wirklich begeistert vom Tutorial im allgemeinen. Das scrittweise Vorgehen, bin passenden Grafiken dokumentiert, ist m.E. besser als in einigen Büchern.
    Bitte weiter so.
    Was mich interessieren würde ist eine Datekommunikation mit einem Rechner. Also ich habe zum beispiel eine App wo ich daten (von Hand) erfasse. Zur Auswertung sollen diese aber Langfristig auf einen externen Rechner übertragen werden, und übersichtsresultate vom externen Rechner (der gegebenenfalls ja Daten von x Endgeräten kombiniert) zum “pod”.
    Hier wäre vielleicht eine Anregung für ein Tutorial.

    mfg
    Marcel

    • Felix says:

      Hallo Marcel,

      meinst Du damit ein Tutorial über das Synchronisieren mit einem Mac oder PC über iCloud?
      Das wäre eine Idee, ist aber nicht ganz einfach.

      Grüße
      Felix

  3. Marc says:

    Hi Felix,

    hoffe Du kannst helfen, habe dank Deinem Tutorial den UIScrollView implementiert,
    funktioniert alles super nur wie platziere ich Objekte via InterfaceBuilder auf das Image
    innerhalb der UIScrollView Class auf Bereiche die ich im IB nicht sehen kann?

    IB scrollt nicht nach unten, auf dem iPhone kann ich scrollen.

    Pls. help.

    Cheers,
    Marc

    • Felix says:

      Hallo,

      das ist leider nicht ganz einfach. Es gibt aber prinzipiell zwei Möglichkeiten das zu bewerkstelligen. Man könnte beispielsweise die Position jedes Objects manuell im Size inspector setzen, was natürlich viel Arbeit ist.
      Besser ist es den Inhalt des Scroll Views in eine extra xib zu verlagern. Das funktioniert so:
      1. Rechtsklick auf den Projektordner und dann New File…
      2. In der Kategorie User Interface dann das Template “Empty” wählen und die neue Datei erstellen
      3. Ziehe dann einen View in den Editor-Bereich und passe die Größe beliebig an. Jetzt kannst Du die Objects an die gewünschte Stelle setzen
      4. In “ViewController.m”, also in der Datei, in der sich das Outlet des Scroll Views befindet, musst Du dann nur noch folgenden Code in viewDidLoad einfügen:

      NSArray *xibContents = [[NSBundle mainBundle] loadNibNamed:@"ScrollContent" owner:self options:nil];
      UIView *view = [xibContents lastObject];
      [scrollView addSubview:view];
      scrollView.contentSize = view.frame.size;

      Hier wird einfach nur der große View aus der .xib-Datei geladen und auch gleich die contentSize des Scroll Views passend gemacht.

      Natürlich darf man nicht vergessen den Image-View in “MainStoryboard.storyboard” aus dem UIScrollView zu entfernen.

      Das war’s auch schon.
      Ich hoffe ich konnte dir helfen.

      Grüße
      Felix

      • Christopher says:

        Hallo Felix,

        vielen Dank für deine wunderbaren Tutorials, hier habe ich bisher immer eine Lösung gefunden.

        Allerdings steht ich nun vor einem Problem das hier zwar gelöst wurde, mich aber zu einem anderen Problem geführt hat.

        Ich habe eine Anwendung die auf der Startseite ein kleines Menü mit einigen Buttons darstellt. Jeder dieser Buttons führt weiter auf die jeweilige ViewControll.

        Da sich dieses Menü endlos mit Buttons erweitern lassen sollte, habe ich mich entschlossen auf der Startseite nur noch einen Scrollview einzubinden und den Content in eine .xib auszulagern, wie oben beschrieben.

        Jetzt stehe ich allerdings vor dem Problem: Wie kann ich aus den Buttons in der .xib mitteilen, dass Sie einen ViewControll aus meinem Storyboard aufrufen sollen?

        Ich hoffe du kannst mir behilflich sein.

        MfG.

        Christopher

        • Felix says:

          Hallo Christopher,

          damit das ganze funktioniert, musst Du die Klasse des File’s Owner der xib ändern. Und zwar gibst Du einfach den Namen des View Controllers der Startseite ein (im Identity inspector). Dann kannst Du wie gewohnt die Touch Up Inside-Methoden im Startseiten-View-Controller erstellen.
          Um die View Controller aufzurufen, musst Du im Storyboard Segues vom Startseiten-View-Controller (der mit dem Scroll View) zu den einzelnen View Controllern, die angezeigt werden sollen, erstellen. Wichtig ist, dass die Segue wirklich von VC zu VC geht, also am besten einfach im Documents Outline mit ctrl auf den Startseiten-VC klicken und dann auf den jeweiligen anderen VC ziehen. Dann musst Du diese Segues auswählen und im Attributes inspector einen Identifier festlegen, z.B. “ShowVC1″. In der .m-Datei des Startseiten-VCs kannst Du dann in jede Button-Methode diesen Code einfügen:

          [self performSegueWithIdentifier:@"ShowVC1" sender:self];

          Natürlich musst Du die Identifier für jeden Button anpassen.

          Dann sollte alles funktionieren.

          Wenn Du noch Fragen hast, gib Bescheid.

          Viele Grüße
          Felix

  4. Marc says:

    Hallo,

    Du schreibst: Die App wird eine einzelne Scene mit einem Scroll View sein.
    Dieser wird ein Bild mit den Maßen 320×900 enthalten, also zu groß für
    das Display.

    Das iPhone 4 hat doch eine Resolution von 640×960.
    Beziehst Du Dich auf das iPhone 3?

    Gruß,
    Marc

    • Felix says:

      Hallo,

      ja das ist die Auflösung für das iPhone 3gs. Wenn man eine App entwickelt muss man immer auch einplanen, dass sie auf einem älteren Gerät gestartet wird. Auf einem iphone 4(s) kann man die App auch mit schlechterer Auflösung benutzen, andersrum geht das nicht. Wenn man also eine App mit vielen Bildern (ein Spiel oder ähnliches) entwickelt, muss man tatsächlich die Bilder für beide Auflösungen zur Verfügung stellen.

      Grüße
      Felix

  5. Georg says:

    Hallo Felix,

    vielen Dank für die schnelle Antwort. Leider ist das Tutorial was Du in deinem Antwort verlinkt hast nicht das was ich suche :(

    Also mein Problem ist folgendes:
    Ich muss ein iPhone App entwickeln. Die App soll nur ein Produktkatalog sein. Wenn man die App öffnet soll unserer Firmenlogo erscheinen mit ein Button der zu den Kategorien-Übersicht führt. Die Kategorien bestehen auch nur aus Buttons und jeder Button führt zu einer TableView (Wo die einzelne Produkte aufgelistet sind) wenn man auf ein Produkt drückt öffnet sich ein ViewController mit ein Bild von dem jeweiligen Produkt und ein bisschen Beschreibung dazu!

    So das habe ich alles realisiert mein Problem liegt nur bei der Beschreibung von den einzelnen Produkten. Die Beschreibung soll in ein ScrollViewer integriert werden damit ich etwas mehr Text schreiben kann als das was auf dem iPhone Bildschirm passt!

    Das heißt ich muss mehrere ContollViewers hinzufügen (für jeden Produkt eins) und Pro ControllViewer brauche ich ein ScrollViewer!

    Ich habe versucht in dem folgendem Bild das Problem Grafisch darzustellen. Alles was rot ist, ist das was ich nicht geschafft habe!

    http://img815.imageshack.us/img815/7672/katalog.png

    Ich wäre für eine schnelle Hilfe sehr dankbar :)

    Vielen Dank!
    Georg

    • Georg says:

      Hallo Felix,
      es hat sich erledigt… Ich habe es raus :)
      Danke dir trotzdem!
      Lieben Gruß,
      Georg

      • Andy says:

        hi gregor

        wie hast du es gelöst? ich stehe vor dem selben problem: ich weiss nicht, wie ich labels ausserhalb der view auf dem storyboard platzieren kann.

        • Felix says:

          Hallo Andy,

          weiter oben gibt es ein Kommentar von Marc mit dem selben Problem (2. Kommentar von oben). Darunter steht eine Anleitung, wie das möglich ist.

          Grüße
          Felix

  6. Georg says:

    Erstmal vielen vielen Dank für dein hilfreichen Tutorial.
    Kannst Du mir bitte erklären, wie ich in einem Projekt mehrere ViewControllers mit jeweils einen Scrollviewer realisieren kann?!!!

    Also ich brauche eine Seite (ViewController) mit mehrere (Round Rect Buttons) und jeder Button führt zu einem (Table View Controller) und jeder Zeile von dem (Table View Controller) führt zu einen (ViewController) der einen ScrollView beinhaltet!

    Hab bis jetzt alles realisiert bist auf die ScrollViewers :(

    Ich kann irgendwie nur ein ScrollViewer für das Ganze Projekt verwenden! Ich brauche aber mehrere >>> Für jede Seite Eins!

    Ich wäre für eine schnelle Antwort sehr dankbar :)

    Vielen Dank!

    • Felix says:

      Hallo,

      so ganz habe ich dein Problem nicht verstanden. Ich denke das Problem liegt bei den Detail Views des Table View Controllers, die jeweils einen Scroll View enthalten sollen. In diesem Tutorial wird gezeigt wie das mit den Detail Views im Storyboard funktioniert. Vielleicht hilft dir das weiter.
      Kurz gesagt erstellst Du einen Detail View Controller mit dem Scroll View und rufst diesen dann mit verschiedenem Inhalt immer auf, wenn eine Zeile im Table View Controller ausgewählt wird.

      Falls dir das oben genannte Tutorial nicht weiterhelfen sollte, müsstest Du mir genauer erklären, was nicht funktioniert.

      Grüße
      Felix

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*


9 × neun =

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>