overridden three20 TTDefaultStyleSheet style not working - iphone

i recently got three20 integrated into my app and am trying to override the default toolbar color in TTWebController.
In TTWebController.m:118 I see that this is setting the toolbar's tintColor:
_toolbar.tintColor = TTSTYLEVAR(toolbarTintColor);
So I created my own stylesheet that subclasses TTDefaultStyleSheet and overrides toolbarTintColor
FooStyleSheet.h:
#import <Three20Style/Three20Style.h>
#import <Three20Style/TTStyleSheet.h>
#import <Three20Style/TTDefaultStyleSheet.h>
#interface FooStyleSheet : TTDefaultStyleSheet
#property (nonatomic, readonly) UIColor* toolbarTintColor;
#end
FooStyleSheet.m:
#import "FooStyleSheet.h"
#implementation RaptrStyleSheet
- (UIColor*)toolbarTintColor {
return RGBCOLOR(0, 0, 0); // should override TTDefaultStyleSheet
}
#end
and in my application:didFinishLaunchingWithOptions: i set my default stylesheet
[TTStyleSheet setGlobalStyleSheet:[[[FooStyleSheet alloc] init] autorelease]];
but when I view the TTWebController, it doesn't inherit my tintColor. If I edit TTDefaultStyleSheet.m directly:
- (UIColor*)toolbarTintColor {
return [UIColor blackColor];
}
it works as expected.
Is there something I am overlooking that is preventing my style to be picked up?
thanks,
-norm

In your header file, the #property is unnecessary - does removing this solve your problem?

Related

How to add a popup UIView (of a customized class) on a UIViewController

I'm new on this, and I would like to get some advice because I don't know what I'm doing wrong.
I want to make an app in xcode, with a UIView with some items, and when you do something, another UIView (smaller than the first) pops up above the first UIView. The popup UIView would be a customized class.
I have started with the UIViewController template and the initial UIView, and I have linked all the items in the .storyboard, and it works. But when I create my own UIView class (from objective-C class), put the second UIView over the first in the storyboard and link it to my class, something goes wrong.
The UIView appears, but when I try to set it to hidden, it doesn't answer. It's like it's not receiving the messages, so I think I don't link it well programmatically and just appears because of the storyboard.
I don't know if I have to create another UIViewController instead of the UIView, or if this is the correct path.
Can anybody explain me a little, or just write a little code snippet with the instantiation of the second view and adding it?
Lots of thanks!!
(I paste some code, of the declaration in .h and instantiation in .m)
#import <UIKit/UIKit.h>
#import "EditView.h"
#interface ReleaseViewController : UIViewController <UIWebViewDelegate, UISearchBarDelegate> {
IBOutlet UIWebView *web;
IBOutlet UISearchBar *search;
IBOutlet EditView *evHack;
}
#property (nonatomic, retain) IBOutlet UIWebView *web;
#property (nonatomic, retain) IBOutlet UISearchBar *search;
#property (nonatomic, retain) IBOutlet EditView *evHack;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
search.delegate = self;
web.delegate = self;
evHack = [evHack initWithFrame:CGRectMake(0, 44, 320, 377)];
[evHack setHidden:YES];
}
EditView Class (I still have nothing):
#import <UIKit/UIKit.h>
#interface EditView : UIView
#end
#import "EditView.h"
#implementation EditView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(#"View created");
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
initWithFrame only works when you alloc/init an app. If its already initialized, in this case by the storyboard, just set its frame:
evHack.frame = CGRectMake(0,44, 320, 377);
I don't know what it looks like in IB, But setting its frame in code may be redundant if you set it in IB too. To check whether evHack is hooked up right, NSLog evHack in viewDidLoad. If you get nil back, it's not hooked up right.

Custom UINavigationController with button

I would like the NavigationBar to behave the same but would like to change the appearance of it. I've found so many ways of doing this online but I'm not sure which one is the best result for iOS 5.0. The navigation bar will look like this:
Since you are targeting iOS 5 i would definitely go for customizing UINavigationBar using the Appearance proxy. Then you can easily set your own images and they will apply to all navigation bars in your application without subclassing.
You can also customize the buttons in the navigation bar by customizing UIBarButtonItem. There are method like backButtonBackgroundImageForState:barMetrics: for the back button and backgroundImageForState:barMetrics: for the other buttons.
I had been looking for this thing for ages, too, without finding a straightforward solution! Thanks to an friend of mine, and sample codes, we made it with a custom navigation bar class that can be imported into any view controller class.
The .h file:
#import <UIKit/UIKit.h>
#interface NATitleBar : UIView {
NSInteger tag;
}
#property ( nonatomic) IBOutlet UIImageView *imageView;
#property ( nonatomic) IBOutlet UILabel *label;
#property ( nonatomic) IBOutlet UIButton *back;
#property ( nonatomic) IBOutlet UIButton *home;
/**
* Supports UIButton-style adding targets
*/
#end
The .m file:
#import "NATitleBar.h"
#implementation NATitleBar
#synthesize imageView;
#synthesize label;
#synthesize back;
#synthesize home;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSArray *views = [[NSBundle mainBundle] loadNibNamed:#"NATitleBar" owner:self options:nil];
[self addSubview:[views objectAtIndex:0]];
// customize the view a bit
//self.imageView.layer.borderWidth = 1.0;
//self.imageView.layer.borderColor = [UIColor colorWithWhite:0.4 alpha:0.4].CGColor;
//self.imageView.clipsToBounds = YES;
//self.imageView.layer.cornerRadius = 5.0;
}
return self;
}
#pragma mark - Overriden Setters / Getters
- (void)setTag:(NSInteger)aTag {
self.back.tag = aTag;
}
- (NSInteger)tag {
return self.back.tag;
}
#end
and then for the Nib file we have the following:
You can add or delete images in the Nib file to make the GUI as you wish.
Now you must import the class into any view controller you wish to have with custom navigation controller, and also define two methods (or one, if you don't want the 'home' button. in .h :
- (void) back;
in .m:
- (void)back {
[self.navigationController popViewControllerAnimated:YES];
}

resize the Hosting View through addSubview in Core-Plot in XCode 4

I'm running into a wall trying to resize the Hosting View. The problem is I either get a full-screen plot or a blank screen. I'm hoping to get some leads to fix this problem:
I'm using Xcode 4 | IOS 4.3 | Recently downloaded core plot using hg:
I have two xib files (MainWindow & my ViewController)
My ViewController.xib file contains two objects: a View and Hosting View both at the same level:
+-View
+-Graph Hosting View
I get no erros in my code, but all I get a blank screen. I've searched for 3 days how to get around this problem, but haven't found something that works.
My xAppDelegate.h
#import <UIKit/UIKit.h>
#class CorePlotTestViewController;
#interface CorePlotTestAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet CorePlotTestViewController *viewController;
#end
My ViewController.h
#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"
#interface CorePlotTestViewController : UIViewController <CPTPlotDataSource>
{
CPTXYGraph *graph;
NSMutableArray *dataForPlot;
CPTGraphHostingView *graphView;
}
#property(readwrite, retain, nonatomic) NSMutableArray *dataForPlot;
#property(nonatomic, retain)IBOutlet CPTGraphHostingView* graphView;
My ViewController.m
#import "CorePlotTestViewController.h"
#interface CorePlotTestViewController(private)
- (void) configureTableHeader;
#end
#implementation CorePlotTestViewController
#synthesize dataForPlot;
#synthesize graphView;
-(void)dealloc
{
[dataForPlot release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configureTableHeader];
}
- (void) configureTableHeader
{
// here I implement the contents of the Hosting View
graph = [[CPTXYGraph alloc] initWithFrame: CGRectZero];
CPTGraphHostingView *hostingView = [(CPTGraphHostingView *)[CPTGraphHostingView alloc]
initWithFrame:CGRectZero];
[self.view addSubview:hostingView];
...
// etc
...
}
In your code, you initialize the hosting view using a CGRectZero frame, which is basically a frame with an origin at (0,0) and both a width and a height of 0 px. It is the reason why you don't see the graph at all when you run your project.
If you gave a custom size and location to the hosting view in Interface Builder, it is overridden by this code.
By the way, I'm not sure why you want to add the hosting view to the controller's view in the code. You just need to layout both components using Interface Builder, giving the hosting view the size and the location you want it to have.
Last thing : why do you add a 'T' to Core-Plot class names ? CPTPlotDataSource should simply be CPPlotDataSource; CPTXYGraph: CPXYGraph; etc.

QLPreviewController - setting previewItemTitle

I can't work out how to set the previewItemTitle property for my QLPreviewController class. Its seems a bit strange as the iPhone developer document for this class says that that property is #property (readonly) which would mean that I cannot set it.
Any ideas. Thanks
My code:
QLPreviewController *preview = [[QLPreviewController alloc] init];
[preview setDataSource:self];
[self presentModalViewController:preview animated:YES];
QLPreviewController has no previewItemTitle property. You mean the QLPreviewItem protocol.
"Readonly" means that you can't set it via the property (unless it's overridden); i.e. the property does not declare a setPreviewItemTitle: method. This makes sense for the protocol: the controller does not expect to be able to set the preview item titles.
For the most basic preview item, you could use something like this:
#interface BasicPreviewItem : NSObject<QLPreviewItem>
{
}
#property (nonatomic, retain) NSURL * previewItemURL;
#property (nonatomic, copy) NSString* previewItemTitle;
#end
#implementation BasicPreviewItem
#synthesize previewItemURL, previewItemTitle;
-(void)dealloc
{
self.previewItemURL = nil;
self.previewItemTitle = nil;
[super dealloc];
}
#end
However, the point of the protocol is so that you can take any class and add -(NSURL*)previewItemURL and -(NSString*)previewItemTitle methods (e.g. if you had a music player, you could add those methods to the "Track" class and be able to preview tracks).

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.