Programmieren mit Swift - Für macOS und iOS
Programmieren mit Swift - Für macOS und iOS
Bindung an einen NSView, Teil 2

Die nächste Aufgabe besteht im Hinzufügen von zwei Schiebereglern für die horizontale und vertikale Positionierung. Auch die Slider sollten so konfiguriert werden, dass sie sich bei Veränderungen der Fenstergröße anpassen.
stacks_image_42005396-0AC5-42FC-8BFF-194F0A97FBEF
Für die Steuerelemente gibt es passende Gegenstücke im Programmcode. Für das DrawingView gibt es direkt ein Outlet, das im Interface Builder mit dem View auf dem Programmfenster verbunden werden muss. Die Schieberegler hingegen kommen ohne Outlet und auch ohne Action aus. Sie werden an Eigenschaften des Controllers gebunden.

Die GraficBindingAppDelegate.h
#import <Cocoa/Cocoa.h>
#import
"DrawingView.h"

@interface GraficBindingAppDelegate : NSObject
{
    NSWindow *window;

    IBOutlet DrawingView *theDrawingView;
    int sliderXValue;
    int sliderYValue;
}

@property (assign) IBOutlet NSWindow *window;

@property (readwrite) int sliderXValue;
@property (readwrite) int sliderYValue;

@end
Der horizontale Schieberegler wird an die Eigenschaft sliderXValue gebunden, der vertikale Schieberegler an die Eigenschaft sliderYValue. Im Interface Builder sehen diese Verbindungen dann so aus:
stacks_image_EA2537B7-2AD6-427E-9720-FAB9EB625682
Jetzt sind zwar die Schieberegler mit Werten in Controller verbunden, aber noch nicht das DrawingView mit diesen Werten. Diese Datenbindung wird auch nicht im Interface Builder gemacht, sondern im Programmcode. Xcode hat für den Controller automatisch auch die Methode applicationDidFinishLaunching generiert. Das ist genau der richtige Ort, um die Bindung zu erzeugen.

Die GraficBindingAppDelegate.m
#import "GraficBindingAppDelegate.h"

@implementation GraficBindingAppDelegate

@synthesize window;
@synthesize sliderXValue;
@synthesize sliderYValue;

- (
void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [theDrawingView bind:
@"positionXpercent" toObject:self
     withKeyPath:
@"sliderXValue" options:nil];

    [theDrawingView bind:
@"positionYpercent" toObject:self
     withKeyPath:
@"sliderYValue" options:nil];
}

@end
Da die Eigenschaften als Zeichenketten verwendet werden, liegt der Schluss nahe, dass hier Key-value-Coding zu Einsatz kommt. Und genau so ist es auch. Cocoa-Binding basiert auf KVC.

Nachdem auch das Binding zu dem DrawingView hergestellt ist, könnte man meinen, die Anwendung sei jetzt fertig, aber wenn Sie Ihre Arbeit testen, werden Sie schnell feststellen, dass sie nicht funktioniert. Aber keine Angst, Sie haben keinen Fehler gemacht. Nur ein kleines, aber entscheidendes Detail fehlt noch: Das View muss dazu gebracht werden, sich selbst neu zu zeichnen, wenn sich einer der angebundenen Werte ändert. Bisher tut es das nämlich nicht automatisch.
Der einfachste Weg ein Neuzeichnen zu bewirken, ist die Verwendung von speziellen Accessor-Methoden. Zwar werden im View bisher nur Properties verwendet, was aber nicht bedeutet, dass man nötigenfalls nicht doch Accessor-Methode verwenden kann. Die vom Compilier automatisch generierten Methode werden überschrieben.

Erweitern Sie die DrawingView.m Datei um die beiden folgenden Methoden.
-(void)setPositionYpercent:(int) f
{
    if (f != positionYpercent)
    {
        positionYpercent = f;
        [
self setNeedsDisplay:YES];
    }
}

-(
void)setPositionXpercent:(int) f
{
    if (f != positionXpercent)
    {
        positionXpercent = f;
        [
self setNeedsDisplay:YES];
    }
}
Leicht ist zu erkennen, dass bei der Zuweisung eines neuen, aber unterschiedlichen Wertes die Methode setNeedsDisplay aufgerufen wird. Dieser Aufruf bewirkt ein Neuzeichnen des View, und jetzt kann auch endlich das Rechteck mit den Schiebereglern bewegt werden.
stacks_image_0CB8E5A3-E0FF-4C38-AE90-775E9F7B3808