Bronze & Silver challenge


#1

Hello all, was hoping you could look at this and see if i solved it and did it properly.

Bronze Challenge

So for this, i created a new subclass of UIViewController. I added the MapKit framework to my project and imported it. Then i wrote this

[code]- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.

MKMapView *theMapView = [[MKMapView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self setView:theMapView];

}[/code]

And that seems to do it actually :slight_smile:

Silver Challenge
Now, a little more tricky as expected. I did it programmatically, so first i created the segmented control:

[code] // Create segmented control to screen
segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@“Red”, @“Green”, @“Blue”, nil]];

// Set Frame
[segment setFrame:CGRectMake(125, 50, 150, 50)];

// Add method to call every time user changes values
[segment addTarget:self
            action:@selector(segmentValueChanged)
  forControlEvents:UIControlEventValueChanged];

// Add it to the view
[v addSubview:segment];[/code]

Now that it is on the screen i turned to the method to change the color. This got me stumbled for some time, but then i decided to make the view and instance variable of the view controller, so that i had direct access to it in my segmentValueChanged method so i could call the setCircleColor: i tried to do something like [self.view setCircleColor] but it didn’t work, but i’m not sure the way i did it is good enough or bad programming, so let me know aye :slight_smile:

[code]-(void) segmentValueChanged
{

// Check which value the segment holds
if (segment.selectedSegmentIndex == 0)
{
    // Red - create UIColor object
    [v setCircleColer:[UIColor redColor]];
}
else if (segment.selectedSegmentIndex == 1)
{
    // green
    [v setCircleColer:[UIColor greenColor]];
}
else if (segment.selectedSegmentIndex == 2)
{
    // Blue
    [v setCircleColer:[UIColor blueColor]];
}
else
    NSLog(@"None selected");

// Create a new view to be added to screen

}[/code]

And again, the ‘v’ is the HypnosisView, which is an instance variable of the viewController.

Thanks on advance,
Best Regards, JBJ


#2

I did it in a similar way, but I have a couple of questions. Maybe someone can answer.
[ul][li]I added the color changing method to the HypnosisView, not the controller. Does it make a difference where you add it? [/li][li]Is there a way to use the xib along with the programmatic drawing? I’ll check the other posts in the forum to see if anyone did it this way, but I thought I’d ask, since I’m here.[/li][/ul]

Thanks


#3

Hey Seerex.

I was trying the same approach but got stuck trying to call the instance method setCircleColor. I also tried with [self.view setCircleColor] but as you know does not work.

I’m curious about how did you make the view and instance variable of the view controller to get access to the method.

Can you give me a hint?

thanks.


#4

Hi,

you mentioned to

How did you do that?

I have done that so far:

[code]- (void)segmentAction:(id)sender
{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
NSInteger index = segmentedControl.selectedSegmentIndex;

//allocieren und initiieren der Instanz von "v"
v = [[HypnosisView alloc] init];

switch (index) {
	case 0:
	{
        [v changeCircleColor:index];
        [v sayHello];
        
        NSLog (@"Selected Index: %i", index);
		break;
	}
	case 1:
	{
        [v changeCircleColor:[segmentedControl selectedSegmentIndex]];
        NSLog (@"Selected Index: %i", index);
        break;
	}
    case 2:
    {
    [v changeCircleColor:[segmentedControl selectedSegmentIndex]];
    NSLog (@"Selected Index: %i", index);
        break;
    }
 
}
//Set the updated View
[self setView:v];[/code]

But then my SegmentedControl disappears. What to do to keep it correctly on its place?

Thank you and regards,
Stefan


#5

I manage to use XIB to complete silver challenge. This is how I did it:

  1. Subclass UIViewController and created HypnosisViewController.xib
  2. In HypnosisViewController.xib Add View
  3. Change UIView’s custom class to HypnosisView
  4. Add Segmented Control
  5. In HypnosisViewController.h include HypnosisView.h and add and IBOutlet
    IBOutlet UISegmentedControl *color;
  6. Back to HypnosisViewController.xib Connect color to Segmented Control
  7. In File’s owner, change custom class to HypnosisViewController
  8. connect File’s owner’s view to HypnosisView
  9. in HypnosisViewController.m Make sure you initWithNibName call the following with nils
    self = [super initWithNibName:nil bundle:nil];
  10. Take out - (void)loadView completed (otherwise, it will overwrite the view created by xib.)
  11. now you can reference HypnosisView in xib with [self view]. The only problem is view method return UIView, so you cannot call setCircleColor: To do that all you have to do is to cast it to HypnosisView by [(HypnosisView *)[self view] setCircleColor:[UIColor redColor]];

#6

Hi guys,

looking at another post i have discovered how to do [self.view setCircleColor]. You have to do [b[/b]self.view setCircleColor]. This works for me. In particular, in my switch I do:

[(id)self.view setCircleColor:[UIColor redColor]];

That happens because we don’t have a really good Objective-C knowledge… (At least me :slight_smile:

Regards, Albert


#7

[quote=“albertvila”]Hi guys,

looking at another post i have discovered how to do [self.view setCircleColor]. You have to do [b[/b]self.view setCircleColor]. This works for me. In particular, in my switch I do:

[(id)self.view setCircleColor:[UIColor redColor]];

That happens because we don’t have a really good Objective-C knowledge… (At least me :slight_smile:

Regards, Albert[/quote]

Well the reason self.view per se not being able to call setCircleColor is because of the concept of polymorphism. self.view basically is of type UIView.Now earlier when we had done an assignment— self.view= [[HypnosisView alloc] initWithFrame:[[UIBounds bounds] screen]] what we actually did was assigning a HypnosisView object to UIView type pointer. Now since HypnosisView is a subclass of UIView, the type of messages that you wud be able to send to self.view pointer is going to be all those methods that HypnosisView inherited from UIView. Whats more, you will be able send updated methods (overriding methods) to a UIView pointer. However there’s one problem.UIView pointer (being of baseclass) would not be able to call a method that is wholly specific to a Subclass i.e created in HypnosisView e.g.-setCircleColor. So we need to first typecast UIView pointer into a Subclass type. This process is downcasting. And then call any baseclass specific method. This is a general OOP concept.
[(HypnosisView *)self.view setCircleColor:UIColor.redColor];
Now that being said, Objective C offers a special object type known as ‘id’ which is general purpose object.This basically bypasses Class inheritance principle in some ways. You can use that too.