Een Fahrenheit-Celsius Omzetter

•02/11/2009 • Laat een reactie achter

We proberen eens zelf een oefeningske te maken. Het zal wel al ergens gepubliceerd zijn, omdat het zo’n klassieker is. Desniettemin willen we het zelf eens proberen en vooral de “stap voor stap” bespreking maken.

  1. Start XCode en maak een nieuw project aan. Kies “Windows-based application” van de iPhone en noem het WalkThrough.
  2. we verwijderen de classes die in de map “class” zitten en herschrijven de main.m als//
  3. //  main.m
    //  WalkThrough
    //
    //  Created by Johan Calu on 2/11/09.
    //  Copyright KHBO 2009. All rights reserved.
    //
    #import <UIKit/UIKit.h>

    @interface MyView : UIView
    {
    IBOutlet UITextField *infield;
    IBOutlet UITextField *outfield;
    }
    @end@implementation MyView

    - (IBAction) convert: (id) sender
    {
    float invalue = [[infield text] floatValue];
    float outvalue = (invalue – 32.0f) * 5.0f /9.0f;
    [outfield setText: [NSString stringWithFormat:@"%3.2f", outvalue]];
    }
    @end
    // View controller die autoroteert
    @interface MyViewController : UIViewController
    @end

    @implementation MyViewController

    - (void) loadView
    {
    [super loadView];
    self.view.autoresizesSubviews =YES;
    self.view.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    }

    - (BOOL) shouldAutorotateTointerfaceOrientation : (UIInterfaceOrientation) interfaceOrientation
    {
    return YES;
    }
    @end

    // Application delegate that uses NIB objects
    @interface WalkThroughAppDelegate: NSObject
    {
    IBOutlet UIWindow *window;
    IBOutlet MyView *contentView;
    }
    @end
    @implementation WalkThroughAppDelegate

    - (void) applicationDidFinishLaunching:(UIApplication *) application{
    [window addSubview:contentView];
    [window makeKeyAndVisible];
    }

    - (void) dealloc{
    [contentView release];
    [window release];
    [super dealloc];
    }

    @end

    int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
    }

     

  4. Nu starten we de interface builder door op de “MainWindow.xib” te dubbelklikken. Je zal merken dat er 4 objecten in de Mainwindow nib zitten : File’s owner, First Responder, Window en ook nog een met de naam dat je aan deze toepassing hebt gegeven (WalkThroughAppDelegate). .Er zijn nu 2 tools die interessant zijn om mee te werken als je met de interface builder bezig bent: de Library en de Inspector (beide open je door in de menubalk van de interface builder het item “Tools” te kiezen en daarna de desbetreffende tool.
  5. We zullen nu de WalkThroughAppDelegate aanvullen met 2 outlets : window en contentView. Klik in Library op de drukknop “Classes”. Je krijgt een overzicht van heel wat (systeem) classes, maar ook de eigen class WalkThrough. Selecteer deze. Onderaan verschijnt nu een deelvenster met daarin opnieuw enkele drukknoppen. Klik nu op de drukknop “outlets” en vervolgens op het “+” knopje (onderaan links). Tik nu in : “window” en in het rechterdeel (waar er ‘id’ staat) verander je in “UIWindow”. Druk nu nogmaals op het “+” knopje en tik in “contentView” en verander het rechterdeel (i.p.v. id) naar MyView.
  6. In de Library klik je nu bovenaan op de drukknop “Objects” en zoek naar de UIViewController (Zie figuur hieronder). Sleep dit icoon in het MainWindow.xib venster

     

    ViewController

    ViewController

  7. Herhaal nu dezelfde bewerking met een View object (Figuur hieronder).

     

    View Object

    View Object

  8. Het resultaat ziet er dan uit als in Figuur 3

     

    Figuur 3 : Mainwindow.xib

    Figuur 3 : Mainwindow.xib

  9. Nu veranderen we de naam van de View Controller. Dubbelklik op de View Controller en het scherm van de Inspector moet verschijnen. Klik op de rechterknop () in het Inspector scherm. De Class name is nu “ViewController”; Wijzig dit in “MyViewController”.
  10. We doen nu bijna dezelfde bewerking met het View icoon. Dubbelklik op het View Icoon en in de inspector (rechterknop klikken) verander je de class name van “UIView” naar “MyView”. Nu moeten we nog een action en 2 outlets toevoegen aan dit object. Ga dus naar de Library en klik op het “Class” knopje. Zoek naar de class MyView en selecteer het (door erop te klikken). Onderaan in het venster kan je nu op het knopje “action” klikken. Klik op het “+” knopje (links onder) en voeg de action “convert:” toe (let wel : het dubbele punt niet vergeten). Nu klik je op het “outlets” knopje. We zullen de outlets infield en outfield toevoegen. Druk op het “+” knopje en tik in “infield”.
  11. Nu gaan we MyView opvullen met visuele objecten. Dubbelklik daarop op het MyView icoon – er opent een blanko venster met de titel “MyView”.
    Uit de Library (klik op Objects) kies je 2 labels, 1 drukknop en 2 tekstvelden die je sleept naar het MyView venster. Het resultaat wordt weergegeven in figuur 4.

     

    Figuur 4

    Figuur 4

  12. Herschik nu de UI zodat het eruit ziet zoals in figuur 5.

     

    Figuur 5

    Figuur 5

  13. Klik nu op het linker tekstveld. In Inspector kies je het linkse tabje ( Schermafbeelding 2009-11-02 om 15.38.47 ) en nu kan je daar in “Text Input Traits” het keyboard instellen als “Numbers & Punctuation”. Op die manier worden enkel cijfers en komma’s (of punten) aanvaard. Er rest natuurlijk nog alles met elkaar te verbinden, zodat de juiste bewerking wordt uitgevoerd als je op de drukknop (convert) drukt.
  14. Ga naar het “MainWindow.xib” venster. Terwijl je de ctrl-knop ingedrukt houdt sleep je nu van het icoon van het “application delegate object” (Hier WalkThroughAppDelegate) naar het icoon “window”. Een blauwe lijn moet hierbij zichtbaar worden en als je uiteindelijk de muis loslaat in het Window object komt er een pop-up venster met outlets. Kies hier voor “window” (trouwens de enige keuze).
  15. Nu herhaal je de bewerking, maar ctrl-sleep (ctrl ingedrukt houden terwijl je sleept) van de WalkThroughAppDelegate naar het MyView object. In het pop-up venster selecteer je “contentView”. Wat je in puntje 13 en 14 gedaan hebt is eigenlijk het declareren van de IBOutlet instanties.
  16. Open nu het MyView venster (door te dubbelklikken op het MyView icoon). ctrl-sleep nu tussen het MyView object (in xib) naar het linker tekstveld. Het popupvenster verschijnt waarin je nu “infield” selecteert. Herhaal nu hetzelfde voor het rechter tekstveld, maar kies nu “outfield”. (Opnieuw ken je objecten toe aan de instantievariabelen).
  17. Rechtsklik nu op de Convert knop (in het MyView objectvenster). Er verschijnt een pop-up venster waarin je gans onderaan de tekst “TouchUpInside” vindt met ernaast een cirkel (Figuur 5). Sleep nu van het cirkeltje naar het MyView object in het .xib venster. Als je daar de muis loslaat verschijnt een pop-up venster waarin je ‘convert:’ selecteert. Je hebt hiermee het verband gelegd tussen het klikken op de drukknop en het uitvoeren van de functie convert.

     

    Figuur 5

    Figuur 5

  18. In xib dubbelklik je nu op de View Controller. Er opent een venster. Sleep nu de “MyView” icoon in het open venster. Je zal merken dat het geheel direct “snapt” in het View Controller venster. Bovenaan rechts bemerk je een pijltje. Dit doent om te simuleren wat er gebeurt in horizontale en vertikale stand…. probeer het eens.
  19. Ga nu naar XCode en “build” het project. Voer het ook uit in de simulator…. HET WERKT!

Stanford 02b – walkthrough

•29/10/2009 • Laat een reactie achter

Ditmaal proberen we de walkthrough uit, waarvan je de beschrijving hier vindt.

Hopelijk zullen we het nu eens volledig kunnen uitwerken, zonder noemenswaardige problemen. Wat in de tekst staat herhalen we hier natuurlijk niet meer opnieuw en we geven slechts de probleemmomenten terug.

De eerste moeilijkheid die we ontmoeten is hoe je de “outlet” en “actions” in het object “Controller” moet toevoegen. Je zit in de “Interface Builder” en volgens de beschrijving heb je zopas de naam ‘Controller’ ingevuld in de “Identity Inspector”. Tot daar alles ok. Maar nu staat dat je in het “outlet” deel 3 zaken moet definiëren (numberOfLines – een UILabel – en increaseButton en decreaseButton – beide UIButton. Maar daar sta je dan! Hoe doe je dat. De oplossing die ik gevonden heb is : ga naar ‘Library’. Selecteer ‘classes’ en in het dropdown lijstje kies je de ‘Controller’ dat je daarnet definieerde. (P.S. Het staat gans onderaan). Eenmaal dat gekozen verschijnt er onderaan een vensterke met daarin 4 knopjes : Lineage, Definitions, Outlets en Actions. Klik nu op Outlets en je kan de gegevens invullen (door op de + knop te drukken maak je er eenvolgende bij). Druk dan op Actions en vul daar de 2 actions in op een gelijkaardige manier. Ziezo, dat is opgelost!

Verder loopt alles zoals beschreven tot aan het punt waar je de class uit de voorgaande opgave moet ophalen. Dus daar stoppen we het nu ook.

 

Stanford 02a

•28/10/2009 • Laat een reactie achter

We blijven maar volharden in de boosheid en gaan nu maar voluit om een opdracht (2a) te maken.

De opdracht vind je hier.

Open XCode en maak een nieuw project aan met de naam “stanford02a”. We kiezen voor een “Windows-based application” uit het Application deel van de iPhone.

Main.m ziet eruit als:

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}

Nu voeren we de nodige aanpassingen uit en voegen de lijnen als volgt in

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

PrintPathInfo();
PrintProcessInfo();
PrintBookmarkInfo();
PrintIntrospectionInfo();
PrintPolygonInfo();
[pool release];
return 0;
}

Nu begint we aan section 5 – nl. we creëren een nieuwe class, zoals beschreven in de opgave.

We volgen hiervoor de beschrijving uit de opgave, maar dan moeten we properties toevoegen, die moeten daarenboven readonly zijn (zodat enkel getters worden gegenereerd).  We vonden de inspiratie om dit te implementeren in:

http://www.shrinkrays.net/code-snippets/csharp/objective-c-by-example-for-a-c-developer.aspx

Belangrijk hierbij is te onthouden dat je eerst de variabelen definieert binnen de class (in de interface) en dat je dan na de interface de @property (readonly) definieert. Ook moet je in het (.m) bestand de variabelen met @synthesize toevoegen.

De volgende vraag is om nu settermethodes te implementeren. Hiervoor gaan we ten rade op

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

Voor de logging (fout melding) bekijken we

http://www.cocoadevcentral.com/d/learn_objectivec/

en

http://www.cocoadev.com/index.pl?NSLog

daarmee kunnen we de set-Methode schrijven voor numberOfSides, minimumNumberOfSides en maximumNumberOfSides

Het item 4 (- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;) gebeurt vervolgens. Bekijk hiervoor naar het voorbeeld op: http://www.otierney.net/objective-c.html

Door de initialisatie in te vullen bekomen we een warning! Zoeken op google naar de betekenis van de warning “PolygonShap may not respond to -numberOfSides:andminimumNumberOfSides …. ” leidt ons naar :

http://mosisa.wordpress.com/2009/02/17/objective-c-warning-class-may-not-respond-to-method/
en http://stackoverflow.com/questions/1064082/myobject-may-not-respond-to-message-foo-noob-objective-c-question

maar dit lost mijn probleem niet op. (Het is enkel maar een warning, maar toch heb ik dat liever niet) Ik heb de indruk dat dit komt doordat ik nog niet alles heb geïmplementeerd en dus ga ik gewoon wat verder implementeren en komen we op deze warning terug als alles afgewerkt is (en het zich nog steeds voordoet natuurlijk).

We doen verder…

Implement a custom init method (overriding the version implemented in NSObject) which calls your custom initializer with default values. For example, your generic -[PolygonShape init] method might create a 5 sided polygon with min of 3 sides and max of 10.

we kijken naar :

- http://www.cocoadevcentral.com/d/learn_objectivec/

- http://www.dreamincode.net/forums/lofiversion/index.php/t71010.html

Het eigenaardige hier is dat ‘initNumberOfSides’ niet herkend wordt. Je kan dus deze initializer niet gebruiken hier, of doe ik iets verkeerd?

Maar we gaan opnieuw verder:

The angleInDegrees and angleInRadians properties should not be stored in an instance variable since they are all properties derived by the numberOfSides. These properties do not need to be synthesized and you should implement methods for each of them which return the appropriate values. We’re being boring and using regular polygons so the angles are all the same.
Dat lijkt me nog ingewikkeld op het eerste zicht.

Door tijdsgebrek wordt deze poging hier niet verder afgewerkt.

De listing tot nu toe is:

PolygonShape.h

//
//  PolygonShape.h
//  stanford02a
//
//  Created by Johan Calu on 27/10/09.
//  Copyright 2009 KHBO. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface PolygonShape : NSObject {
int numberOfSides;
int minimumNumberOfSides;
int maximumNumberOfSides;
float angleInDegrees;
float angleInRadians;
NSString* name;

}

@property int numberOfSides;
@property int minimumNumberOfSides;
@property int maximumNumberOfSides;
@property (readonly) float angleInDegrees;
@property (readonly) float angleInRadians;
@property (readonly) NSString* name;

- (id)initWithNumberOfSides:(int)sides
minimumNumberOfSides:(int)min
maximumNumberOfSides:(int)max;
- (id) init;

@end

en ook :

//
//  PolygonShape.m
//  stanford02a
//
//  Created by Johan Calu on 27/10/09.
//  Copyright 2009 KHBO. All rights reserved.
//

#import “PolygonShape.h”

@implementation PolygonShape
@synthesize angleInDegrees, angleInRadians, name;

@dynamic minimumNumberOfSides;
- (void) setMinimumNumberOfSides:(int)aValue{
if (aValue >= 2){
minimumNumberOfSides = aValue;
}
}

@dynamic maximumNumberOfSides;
- (void) setMaximumNumberOfSides:(int)aValue{
if (aValue <= 12){
maximumNumberOfSides = aValue;
}
}

@dynamic numberOfSides;
- (void)setNumberOfSides:(int)aValue{
if (numberOfSides < minimumNumberOfSides || numberOfSides > maximumNumberOfSides){
NSLog ( @”Invalid number of sides: %d ligt buiten %d en %d@”, numberOfSides,  minimumNumberOfSides, maximumNumberOfSides);
} else {
numberOfSides = aValue;
}

}

- (id)initWithNumberOfSides:(int)sides
minimumNumberOfSides:(int)min
maximumNumberOfSides:(int)max{
self = [super init];

if (self){
[self numberOfSides : sides andminimumNumberOfSides : min andmaximumNumberOfSides : max];
}
return self;
}

- (id) init{
if (self = [super init]){
numberOfSides = 5;
minimumNumberOfSides = 3;
maximumNumberOfSides = 10;
}
return self;
}

@end

einde tot nu…. misschien werken we hier later verder aan.

Stanford : tweede oefening – we beginnen met Objective-C

•26/10/2009 • Laat een reactie achter

De tweede opdracht vind je hier.

We zullen hier nu ook stap voor stap de opdracht uitvoeren en becommentariëren. (Natuurlijk is het de bedoeling om niet telkens alle details te herhalen. Wat in vorige posts in detail werd uitgelegd, wordt niet meer herhaald).

Lees het inleidende deel (tot pagina 3) en bekijk ook eens deze referenties:

Open een nieuw project (noem het ‘Stanford01B’), maar het begint al heel slecht want ik vind de “Command Line Utility” niet in het openingsvenster.

Ik probeer met het “Command Line Tool” te kiezen… en op hoop van zegen doen we verder. Dit trekt er niet op.

We stoppen hier dan maar deze poging!

Stanford : eerste oefening

•25/10/2009 • Laat een reactie achter

We beginnen met de Stanford cursus over de iPhone programmering. Bij iedere les horen een paar oefeningen, we zullen er hier dan ook enkele maken en beschrijven.

We beginnen met de eerste opdracht : (hier te downloaden)

Je moet eerst XCode opstarten natuurlijk. Dat doe je via Finder of via SpotLight (de loupe rechtsboven).

Eenmaal opgestart beginnen we met de nieuwe iPhone applicatie te creëren, zoals in de opgave vermeld. Ik geef er de naam “stanford01a” aan en plaats het in een mapje “workspace”.

  • In Xcode, create a new Window-Based iPhone application.
  • Open the project’s MainWindow.xib file with Interface Builder.
    Door te klikken op MainWindow.xib open je spontaan de Interface Builder. Er openen zich 2 vensters, de ene is de MainWindow.xib zelf (figuur 1) en de andere is het scherm zoals het op de iPhone zal getoond worden (figuur 2).
  • Add the following user interface elements to the view:
    a text label
    an image view

    Hiervoor moet je de tools te voorschijn toveren… Klik in de menubalk van de interface builder op het item “tools” en kies daar de “Library”. Een nieuwe venster verschijnt, met daarin o.a. een text label en een image view (Figuur 3). Klik op het “text label” en sleep het naar het venster. Herhaal de bewerking voor de image view.

  • Set the following properties on the text label
    - text value should be “Hello Stanford!” (or something suitable amusing)

    Er zijn verschillende werkwijzen. De eerste is gewoon op de tekst ‘Label’ klikken in het venster en de tekst wijzigen. De andere manier is gebruik maken van het “Inspector” venster waarin je alle eigenschappen kan wijzigen. We gebruiken de tweede methode en gaan terug in de toolbar van de interface builder op het item “Tools” klikken en daar de “Inspector” kiezen. Een nieuw scherm opent en als je nu ook het ‘Label’ (in de iPhone window) selecteert, dan kan je (o.a.) het veld Text (met daarin de tekst ‘Label’ wijzigen in de tekst “Dag, Oostende” ).
    - text alignment should be centered
    Vermits het Inspector venster open staat kan je dat meteen uitvoeren door op het midddelste icoon van Layout/Alignment te klikken.
    - adjust the size to make the text large
    Ook hier gaan we in Inspector venster de font size op 18 instellen. Vervolgens ga je naar het iPhone venster en maak daar het kader groter, en verschuif het vervolgens horizontaal tot je een blauwe lijn in het midden ziet verschijnen, waardoor de tekst gecentreerd is in het venster.
    - any other properties that catch your eye.
    Naar believen kan je nu de kleur wijzigen, of de achtergrond kleur…. en dit alles in de Inspector
  • Back in Xcode, add an image (.png or .jpg) to your project. You can either drag the image in from the Finder into your project (e.g. into the Resources folder) or you can use the Project > Add to Project… menu to select an image. Note: Be sure to check the “Copy items into destination group’s folder (if needed)” checkbox. If you don’t do this, the resource won’t be inside your project directory and when you submit your assignment the resources will not be included in the submission
    Het gewoon slepen lijkt me eenvoudig, maar toch proberen we het via de “Add to Project…” en kopiëren zeker de foto! (doe dit altijd).  Hier moet je maar letterlijk volgen wat in het Engels beschreven wordt.
  • Once your image is in the project, return to MainWindow.xib, select the image view and set the image for the image view that you dragged in previously using the Attributes Inspector.
    Dit werkt perfekt, zoals beschreven hierboven. De foto zal misschien nog niet volledig zichtbaar zijn, maar dat komt goed met het volgende punt.
  • Configure the image view’s “Mode” to be “Aspect Fit” so that the entire image is scaled to fit inside the image view’s bounds while preserving the aspect ratio of the image. If a different mode works better for your picture, set it accordingly
    Door nu deze “Aspect Fit” te kiezen wordt de foto geschaald zodat het perfect past in deze view. Zo dat is wat we willen.
  • In Xcode, build and run your project in the simulator
    Als je dit uitvoert, dan start de simulator op, maar dan zie ik enkel een wit scherm! Wanneer ik het opstart vanuit de interface builder (dus : File/Simulate interface) dan krijg ik de tekst maar geen figuur!

    De eerste poging is dus geen succes!

Hallo wereld!

•27/09/2009 • Laat een reactie achter

Voilà, hier zijn we dan met een spiksplinternieuwe blog.

Mijn oude blog ( http://calu.edublogs.edu ) wordt met deze geschiedenis.

De dichte kennissenkring zal wel begrijpen waarom. De anderen hebben er het raden naar.