tableHeaderView doesn't display UIView properly - iphone

I'm trying to add UIScrollView with paging as a header to my table, but unfortunately it is not displayed correctly.
The htableHaderView is resized to the size of my imagesScrollView, but only half of it is displayed the rest area is blank.
- (void)viewDidLoad
{
[super viewDidLoad];
ImagesViewController *imagesScrollView = [[ImagesViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
tableView.tableHeaderView = imagesScrollView.view;
imagesScrollView = nil;
}
Thanks for helping

I tried the following code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController
#end
ViewController.m
#import "ViewController.h"
#import "ImagesViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ImagesViewController *imageVC = [[ImagesViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
[[self tableView] setTableHeaderView:[imageVC view]];
imageVC = nil;
}
#end
ImagesViewController.h
#import <UIKit/UIKit.h>
#interface ImagesViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
#property (strong, nonatomic) IBOutlet UIView *ViewInScrollView;
#end
ImagesViewController.m
#import "ImagesViewController.h"
#implementation ImagesViewController
#synthesize ScrollView;
#synthesize ViewInScrollView;
- (void)viewDidLoad {
[super viewDidLoad];
[[self ViewInScrollView] setFrame:CGRectMake(0, 0, 768 * 2, 400)];
[[self ViewInScrollView] setBackgroundColor:[UIColor orangeColor]];
[[self ScrollView] setContentSize:[[self ViewInScrollView] frame].size];
}
#end
ImagesViewController's xib is a view, 768 wide by 200 tall (I made an iPad-based UITableView single-view application). Inside its view is a UIScrollView, set to take up the entire [view frame] area. Then I put a UIView inside of it.
My testing gives me a header that is an orange rectangle, and I can scroll it around as you would expect. This leads me to believe that maybe you need to check the shocks/struts of your imagesScrollView in Interface Builder. Make sure all of the margins and widths are fixed/flexible as you need for it to display properly.

Related

UIScrollView with IUViewController dropping objects

I have a really weird issue with UIScrollView and added UIViewControllers.
It looks like that when UIViewControllers are added to UIScrollView for paging, the UIViewController drops all its added objects.
In the project i have a storyboard with two views and they are connected correctly to the corresponding code.
I know that the code doesn't move the added UIViewController to the correct X, but in this test im only adding one UIViewController so it doesnt matter.
This is the scroll code .h:
#import <UIKit/UIKit.h>
#import "TestViewController.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
#property (strong, nonatomic) NSMutableArray *scrollController;
#end
This is the scroll code .m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.scrollController = [[NSMutableArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated {
//just adding two controllers
TestViewController *first = [[TestViewController alloc] init];
[self.scrollView addSubview:first.view];
[self.scrollController addObject:first];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * self.scrollController.count, self.scrollView.frame.size.height);
self.pageControl.numberOfPages = [self.scrollController count];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This is the viewcontroller code .h:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *lblMsg;
#end
This is the viewcontroller code .m:
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Label: %#", self.lblMsg);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The output in log is:
Label: (null)
Anybody able to see what im doing wrong?
If you create your ViewController using
TestViewController *first = [[TestViewController alloc] init];
your label (IBOutlet) won't be linked.
Navigate to your storyboard in Xcode, select your viewcontroller and assign a unique storyboard id ("myIdentifier") in the identity inspector in utilities on the right hand side.
Try
NSString *identifier = #"myIdentifier";
TestViewController *first = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
Have a look at the documentation:
Each view controller object is the sole owner of its view. You must
not associate the same view object with multiple view controller
objects. The only exception to this rule is that a container view
controller implementation may add this view as a subview in its own
view hierarchy. Before adding the subview, the container must first
call its addChildViewController: method to create a parent-child
relationship between the two view controller objects.

UIScrollView won't scroll when re-entering view

I have a UIView (inside a View Controller, of course), and inside this UIView, I have a UIScrollView. UIScrollView contains some images and buttons. One of the buttons uses the modal Action Segue and opens up a UIView with a MapView inside, and a "back" button at the bottom that takes you back to the previous UIView. But upon going "back" (from the MapView to the UIView), the UIScrollView does not scroll anymore like it did before going to the MapView and back. It's like it's locked in its top position. I feel like it has something to do with delegates? I dunno though, I'm not too clear on those yet. Anyway, any insight to my scrolling issue?? Thanks!!
Here's my .h file (where my scroll view is):
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ThirdViewController : UIViewController <UIScrollViewDelegate, UIScrollViewAccessibilityDelegate>
#property (strong, nonatomic) IBOutlet UIView *findUsView;
#property (weak, nonatomic) IBOutlet UIScrollView *findUsScrollView;
- (IBAction)callButton:(id)sender;
- (IBAction)getDirButton:(id)sender;
#end
Here's my .m file (where my scroll view is):
#import "ThirdViewController.h"
#implementation ThirdViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"appBackgroundColor.png"]];
[self.view addSubview:self.findUsScrollView];
}
-(void)viewWillAppear:(BOOL)animated{
//this line creates the frame of the scrollview (dimensions)
[self.findUsScrollView setFrame:CGRectMake(0, 0, 0, 750)];
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated
{
//dimensions of content within scrollveiw. Scrolling enabaled.
[self.findUsScrollView setScrollEnabled:YES];
[self.findUsScrollView setContentSize:CGSizeMake(0, 751)];
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)callButton:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:0000000000"]];
}
- (IBAction)getDirButton:(id)sender {
}
#end
Here's the .h file for the Map View:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MyMapViewController : UIViewController <MKMapViewDelegate, MKAnnotation>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (weak, nonatomic) IBOutlet UINavigationBar *titleBarMap;
#property (weak, nonatomic) IBOutlet UIToolbar *bottomNavBarMap;
#property (weak, nonatomic) IBOutlet UIView *topTitlesOverlay;
- (IBAction)backButtonMap:(id)sender;
#end
Here's the .m file for the Map View:
#import "MyMapViewController.h"
#implementation BountMapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (IBAction)backButtonMap:(id)sender {
[self dismissViewControllerAnimated:YES completion: ^(void){
ThirdViewController *vc = (ThirdViewController *)[self presentingViewController];
[[vc findUsScrollView] becomeFirstResponder];
}];
}
#end
Try moving [self.findUsScrollView setFrame:CGRectMake(0, 172, 320, 680)]; and [self.findUsScrollView setContentSize:CGSizeMake(320, 680)]; to viewDidLoad as a first suggestion. You don't want those to be called everytime your view appears.
Second, your contentSize and frameSize are the same (320, 680). This means your UIScrollView does not need to scroll. Remember: for a UIScrollView to scroll it's content size must be bigger than it's frame size. That should be all, and of course: setScrollEnabled: YES;
Your override of viewDidAppear is calling [super viewWillAppear:] instead of [super viewDidAppear:]

Issue with UIButton Subclass delegate method

Here is the situation. I have a view controller titled "MyViewController." Within this view controller I have a text editing feature that uses subclassed buttons. The name of the UIButton Subclass is "ColorSwatch"
I have setup delegate/protocol methods in the "ColorSwatch.h" subclass as follow.
// ColorSwatch.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#protocol ColorSwatchDelegate <NSObject>
- (void)fontColor:(UIColor *)color;
#end
#interface ColorSwatch : UIButton {
id <ColorSwatchDelegate> colorSwatchDelegate;
CAGradientLayer *gradient;
UIView *currentView;
UIColor *fontColor;
}
#property (nonatomic, retain) id <ColorSwatchDelegate> colorSwatchDelegate;
#property (nonatomic, retain) CAGradientLayer *gradient;
#property (nonatomic, retain) UIView *currentView;
#property (nonatomic, retain) UIColor *fontColor;
#end
Now in my "ColorSwatch.m" I have:
// ColorSwatch.m
#import "ColorSwatch.h"
#import <QuartzCore/QuartzCore.h>
#import "MyViewController.h"
#implementation ColorSwatch
#synthesize gradient;
#synthesize currentView;
#synthesize colorSwatchDelegate;
#synthesize fontColor;
-(void)setupView{
"Makes the subclassed buttons pretty"
}
-(id)initWithFrame:(CGRect)frame{
if((self = [super initWithFrame:frame])){
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if((self = [super initWithCoder:aDecoder])){
[self setupView];
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
}
return self;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self magnify:view];
fontColor = view.backgroundColor;
[self.colorSwatchDelegate fontColor:fontColor];
}
- (void)magnify:(UIView *)view
{
}
- (void)dealloc
{
[currentView release];
[gradient release];
[fontColor release];
[super dealloc];
}
#end
In the "MyViewController.h" I have:
// MyViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "ColorSwatch.h"
#interface MyViewController : UIViewController <ColorSwatchDelegate> {
UITextField *photoLabelTextField;
}
#property (nonatomic, retain) IBOutlet UITextField *photoLabelTextField;
#end
In the "MyViewController.m" I have:
- (void)fontColor:(UIColor *)color
{
NSLog(#"Selected Font Color");
[self.photoLabelTextField setTextColor:color];
}
Now the delegate method sort of works, meaning when I tap on a color button the
NSLog(#"Selected Font Color");
message gets fired. But the problem is that I cannot change the
[self.photoLabelTextField setTextColor:color];
property. I have tried numerous ways of changing the property, the only thing that I can do is send NSLogs, anything I try to change a property in the "MyViewController" Class nothing happens.
If anyone could please help me out, I would appreciate it.
Thank you
The problem is that the ColorSwatch is sending delegate messages to a dangling instance of MyViewController that it incorrectly allocated in it's initWithCoder: method.
UIControls shouldn't allocate ViewControllers to be their delegates... it goes the other way around.
Delete these lines...
// in ColorSwatch.m initWithCoder:
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
Then, in MyViewController.m ...
- (void)viewDidLoad {
ColorSwatch *colorSwatchButton = [[ColorSwatch alloc] buttonWithType:UIButtonTypeCustom];
// or place a ColorSwatch in the xib, on MyViewController's view... But not before you
// you delete lines from initWithCoder, otherwise it's infinite circular allocation
colorSwatchButton.frame = CGRectMake(/* ... */);
colorSwatchButton addTarget:self action:#selector(csButtonPressed:) forControlEvent: UIControlEventTouchUpInside];
// and so on...
// now the important part:
colorSwatchButton.colorSwatchDelegate = self;
// see - the ViewController is in charge of allocation, sets itself up as the delegate
[self.view addSubview:colorSwatchButton];
}
Instead of building the button in code, you can use IB.
Step 1: make the delegate an outlet...
#property (nonatomic, retain) IBOutlet id <ColorSwatchDelegate> colorSwatchDelegate;
Step 2: draw the buttons in IB, and set their class to ColorSwatch.
Then you can skip the code I wrote in viewDidLoad.
Step 3: The newly placed button should now present an outlet in IB. You can drag from that to the MyViewController as you normally do.
There might be a connection problem in your IBOutlet photoLabelTextField, you may have forgotten to connect xib text field with your photoLabelTextField

Changed nib File to a OPGL ES View, Buttons don't work

Hy,
There is no problmen with changing the nib but when I'm in the nib-File with the OPGL ES view my buttons that are integrated in this view won't work. When I press one the application crashes.
This is the Code how I change the View to the Second Nib:
- (IBAction)drawEAGLView:(id)sender {
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"settingsViewController" owner:self options:nil];
EAGLView* glView = [ nibViews objectAtIndex: 1];
self.view = glView;
[glView startAnimation];}
The Animation is working .
This is the Code of the ViewController where the Button is declared:
SettingsViewController.h:
#import <UIKit/UIKit.h>
#interface SettingsViewController : NSObject {
IBOutlet UIButton *wowButton;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
- (IBAction)wowButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
#end
SettingsViewController.m:
#import "SettingsViewController.h"
#implementation SettingsViewController
#implementation SettingsViewController
#synthesize wowButton;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
//testvarAnimation = 1;
animNext =1;
}
- (void)dealloc {
[wowButton release];
[super dealloc];
}
#end
Here I show you how I connected the Functions and the Outlets:
http://s3.imgimg.de/uploads/screenshotConna91ea645png.png
Please tell me If you need more informations.
Thanks
Hy I solved my problem, I rewrote my drawEAGLView Methode:
- (IBAction)drawEAGLView:(id)sender {
SettingsViewController *sViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[[self.view superview] addSubview:sViewController.view];
}
I also corrected my SettingsViewController.h:
#import <UIKit/UIKit.h>
#class EAGLView;
#interface SettingsViewController : UIViewController {
IBOutlet UIButton *wowButton;
EAGLView *glview;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
#property (nonatomic, retain) IBOutlet EAGLView *glView;
- (IBAction)wowButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
#end
And last but not least I changed my SettingsViewController.m:
#import "SettingsViewController.h"
#import "EAGLView.h"
#implementation SettingsViewController
#synthesize wowButton, glView;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
//testvarAnimation = 1;
animNext =1;
}
- (void)viewDidLoad {
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];
[super viewDidLoad];
}
- (void)dealloc {
[wowButton release];
[super dealloc];
}
#end
I also changed my Nib file. I removed the ViewController and set the type of the File's Owner to my viewController named "SettingsViewController". I connected the File's Owner Outlet view with the EAGLView and the button with the SettingsViewControllers wowButtonPressed Method
I hope I could help also someone else,
Thanks
Here is the right solution for this problem:
First you have to create a parnet object of your view you want to be shown as first.
You need to do this in the header file of the second view.
//
// SettingsViewController.h
// NeheTutorial2
//
// Created by Global Sound on 05.04.11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#class EAGLView;
#class mobilesynthViewController;
#interface SettingsViewController : UIViewController {
IBOutlet UIButton *wowButton;
IBOutlet UIButton *optiButton;
EAGLView *glView;
//mobilesynthViewController *mViewController;
mobilesynthViewController *parent;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
#property(nonatomic,retain) IBOutlet UIButton *optiButton;
#property (nonatomic, retain) IBOutlet EAGLView *glView;
//#property(nonatomic,retain) IBOutlet mobilesynthViewController *mViewController;
#property (nonatomic, retain) mobilesynthViewController *parent;
- (IBAction)wowButtonPressed:(id)sender;
- (IBAction)optiButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
int musicOn;
int isAnimating;
float zaehler;
#end
Now in the implemetaion File you need to add the parent object to your function:
#import "SettingsViewController.h"
#import "EAGLView.h"
//#import "mobilesynthViewController.h"
#implementation SettingsViewController
#synthesize wowButton, optiButton, glView;//,mViewController;
#synthesize parent;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
[parent startThread];
[parent showbButtonStop];
testvarAnimation = 0;
animNext =1;
//musicOn =1;
}
- (IBAction)optiButtonPressed:(id)sender{
NSLog(#"OPTIONS ON");
[self dismissModalViewControllerAnimated:YES];
[parent showbButton];
//mobilesynthViewController *aRootViewController = [[mobilesynthViewController alloc] initWithNibName:#"mobilesynthViewContoller" bundle:nil];
//[self setRootViewController:aRootViewController];
//[aRootViewController release];
//mobilesynthViewController *mViewController = [[mobilesynthViewController alloc] initWithNibName:#"mobilesynthViewController" bundle:nil];
//[[self.view superview] addSubview:mViewController.view];
//self.view = mViewController;
//CGRect rect = [[UIScreen mainScreen] applicationFrame];
//mViewController = [[mobilesynthViewController alloc] initWithFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)];
//self.view = mViewController;
}
- (void)viewDidLoad {
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];
[super viewDidLoad];
}
/*
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
*/
- (void)dealloc {
[wowButton release];
[optiButton release];
[super dealloc];
}
#end
In my case I'm calling a other function in the main View of my program. When the button in the second view is pressed the function in the first view is called through the the parent object
[parent startThread];
Again the startThread methode was declerated in another view.
I hope I could help you.

iPhone MVC. Need some help with understanding how to correctly pass data from Controller to View

A little background:
I'm a C# developer starting to mess with the iPhone (have an idea for a simple 2D game). The only MVC programming I've done was for the web (ASP.NET MVC) so although I do have an understanding in MVC, I can't wrap my mind around one thing. Here's an example to illustrate.
Say I have a simple app where all I want to do is display a big circle on the screen. I created a "View Based Application" and it gave me the basic classes to start with:
MVCConfusionAppDelegate
MVCConfusionViewController
Now since I'll be doing some custom drawing (I know I can add a subview and show the circle that way, but this is just a sample of a larger piece) I've added a class called MyCustomView and in Interface Builder set the View of the MVCConfusionViewController to be a MyCustomView.
Now here's the problem. I want to be able to set in code the size of how big the ball on the custom view should be. So I have a property on the MyCusomView like this:
#import <Foundation/Foundation.h>
#interface MyCustomView : UIView {
NSNumber *ballSize;
}
#property(nonatomic,retain)IBOutlet NSNumber *ballSize;
#end
#import "MyCustomView.h"
#implementation MyCustomView
#synthesize ballSize;
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor redColor]set];
float floatValue = [self.ballSize floatValue];
CGRect ballRect = CGRectMake(50.0f, 50.0f,floatValue , floatValue);
CGContextFillEllipseInRect(context, ballRect);
}
#end
Then, here's my MVCConfusionViewController:
#import <UIKit/UIKit.h>
#import "MyCustomView.h"
#interface MVCConfusionViewController : UIViewController {
NSNumber *ballSize;
}
#property(nonatomic,retain)IBOutlet NSNumber *ballSize;
#end
#import "MVCConfusionViewController.h"
#import "MyCustomView.h"
#implementation MVCConfusionViewController
#synthesize ballSize;
- (void)viewDidLoad {
[super viewDidLoad];
MyCustomView *myView = (MyCustomView *)self.view;
myView.ballSize = self.ballSize;
}
And finally, the MVCConfusionAppDelegate:
#import <UIKit/UIKit.h>
#class MVCConfusionViewController;
#interface MVCConfusionAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MVCConfusionViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MVCConfusionViewController *viewController;
#end
#import "MVCConfusionAppDelegate.h"
#import "MVCConfusionViewController.h"
#import "MyCustomView.h"
#implementation MVCConfusionAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
viewController.ballSize = [NSNumber numberWithInt:200];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
As you can see, there's an ugly cast in my viewDidLoad method. I was hoping I'd be able to make the connection of the ballSize properties in IB, but it won't let me.
So my question simply is, what's the correct way of passing this data from my view controller to my view without doing that cast? I know I'm missing something fundamental, but I just don't see it. Any help would be greatly appreciated!
EDIT: Here's the source code. http://bit.ly/uKyp9 Maybe someone can have a look and see if I'm doing anything wrong.
Are you trying to connect one IBOutlet (in the controller) to another IBOutlet (in the view)? Unfortunately, I don't think it's that easy :-)
You're also storing the data (ballSize) in the controller and the view.
I'd make MVCConfusionViewController a data source for MyCustomView, and then let MyCustomView ask its datasource for the ballSize, inside the -drawRect: method.
#class MyCustomView;
#protocol MyCustomViewDataSource
- (NSNumber *)ballSizeForMyCustomView:(MyCustomView *)view;
#end
#interface MyCustomView {
id<MyCustomViewDataSource> dataSource;
}
#property (nonatomic, assign) IBOutlet id<MyCustomViewDataSource> dataSource;
#end
#implementation MyCustomView
- (void)drawRect:(CGRect) rect {
if (self.dataSource == nil) {
// no data source, so we don't know what to draw
return;
}
float floatValue = [[self.dataSource ballSizeForMyCustomView:self] floatValue];
// ...
}
#end
In Interface Builder, hook MVCConfusionViewController up to the view's dataSource property. Then implement the protocol:
#interface MVCConfusionViewController : UIViewController <MyCustomViewDataSource> {
[...]
}
[...]
#end
#implementation MVCConfusionViewController
- (NSNumber *)ballSizeForMyCustomView:(MyCustomView *)view {
return self.ballSize;
}
#end
This way your view controller could also be the data source for multiple MyCustomViews, because the protocol method takes a MyCustomView as an argument.
If you need more than one ball, have a look at the UITableViewDataSource and implement similar methods, something like:
-(NSInteger)numberOfBallsInMyCustomView:(MyCustomView *)view;
-(NSNumber *)myCustomView:(MyCustomView *) ballSizeAtIndex:(NSInteger)index;
Your view should already be set in IB, so you can use it as is. If you want to use MyCustomView, you can do it like this:
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = CGRectMake(0, 0, 320, 480);
MyCustomView *myView = [[MyCustomView alloc] initWithFrame:frame];
myView.backgroundColor = [UIColor greenColor];
self.view = myView;
[myView release];
CGRect rectangle = CGRectMake(20, 20, 20, 20);
[self.view drawRect:rectangle];
}
I couldn't make your drawing code work, I don't know much about that.
One way to avoid the cast would be to add a separate outlet property for the custom view on the controller, and refer to that instead.
In Interface Builder, make an instance of MyCustomView and drag it into the existing view to make it a subview, then attach it to its own outlet on the controller.