UIWebView Swipe-Gesture - xcode

everything works in my code, but I get always warning by "swipeLeft.delegate = self;"
The "self" is marked by this warning.
The warning is : Passing 'UIWebView *' to parameter of incompatible type
and
Passing 'viewCont *const __strong' to parameter of incompatible type "id UIGestureRecognizerDelegate
What can I do??
My code:
#import "viewCont.h"
#implementation viewCont
#synthesize webView = webView_;
- (void)viewDidLoad
{
//...code
// add Left
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
swipeLeft.delegate = self;
[webView_ addGestureRecognizer:swipeLeft];
//code....
}

Regarding line:
swipeLeft.delegate = self;
Your controller needs to implement UIGestureRecognizerDelegate like follows:
#interface viewCont : UIViewController<UIGestureRecognizerDelegate> {
}
#end
I don't see any problematic code regarding webView warning in provided code.

Is this class a child of UIWebView?
You are setting the target to self, make sure that that object is an instance or subclass of UIWebView. If you have the WebView set up as an instance variable you will need to set the target of the gesture recognizer to that instance.

Related

How do I release this allocation?

I got this code off another thread on here and it works perfectly, but it leaks, and I don't know how to release it. I have tried adding "autorelease" statements to the GoToNext alloc line. It didnt help. Anyone know how to properly handle this?
webView.delegate = [[GoToNext alloc] initWithTarget:self andNext:#selector(loadUpdateGraph)]; //leak
This is the GoToNext code:
.h
#interface GoToNext : NSObject <UIWebViewDelegate> {
id __weak target;
SEL next;
}
-(id)initWithTarget:(id)target andNext:(SEL)next;
-(void)webViewDidFinishLoad:(UIWebView *)webView;
#end
.m
#import "GoToNext.h"
#implementation GoToNext
-(id)initWithTarget:(id)_target andNext:(SEL)_next {
self = [super init];
if (self) {
target = _target;
next = _next;
}
return self;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[target performSelector:next];
}
#end
When you create an instance of GoToNext using alloc, that instance has a retain count of 1. Somewhere in your app you must release this instance before you lose your only reference to it (which in this case is the delegate property of webView). The delegate property of a UIWebView uses assign semantics, so assigning your instance of GoToNext to that property does not retain it. This means that you cannot release or autorelease it while it is still the delegate of webView or webView.delegate will point to deallocated memory.
If you're sure you're only setting webView.delegate once in the lifecycle of the class containing this code, you can get by with just put [webView.delegate release] in the dealloc method of that class. If you're setting it more than once, you might try creating a method like:
-(void)setWebViewDelegate:(id)delegate {
if (webView.delegate) {
[webView.delegate release];
}
webView.delegate = delegate;
}
And using that method to set webView's delegate. There are other ways to handle this situation, but I think this method will probably require the fewest changes to your code.
Of course, in my opinion the best solution of all is to just convert the application to ARC and never have to worry about this kind of thing again.

UILabel subclass

I know that this is a newbie question but I am a newbie so here goes:
I wish to use Chalkduster font quite a lot throughout my app (buttons, labels etc) and have tried subclassing UILabel to achieve this. I have the following in Default.h:
#import <UIKit/UIKit.h>
#interface Default : UILabel
{
UILabel *theLabel;
}
#property (nonatomic, strong) IBOutlet UILabel *theLabel;
#end
and this in my .m:
#import "Default.h"
#implementation Default
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIFont *custom = [[UIFont alloc] init];
custom = [UIFont fontWithName:#"Chalkduster" size:18];
self.font = custom;
NSLog(#"h");
}
return self;
}
#end
When I change the class in interface builder and run, I'm not seeing the Chalkduster font. I'd appreciate a hand in getting this set up as I believe it will save me a lot of time.
Cheers.
Some problems to fix:
1) You're mixing up the idea of Default being a label and Default containing a label. To subclass, get rid of the property inside your class and make your changes to self rather than theLabel (inside the if (self) { section).
2) Anything you code after an unconditional return isn't going to get executed...and I'm surprised the compiler didn't complain about those statements.
Edit: ...and one more thing that just dawned on me.
3) If you're loading from a xib or storyboard, the initialization is done by initWithCoder: instead of initWithFrame:, so:
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
self.font = [UIFont fontWithName:#"Chalkduster" size:18];
}
return self;
}
First of all I don't think that You're subclassing UILabel correctlly. So I made tutorial for You explaining how to do it. You don't need to IBOutlet object which is subclassed. JUST CALL IT WITH SELF. for example: self.font = ... If You want to subclass UILabel do this:
Create new class with title myLabel like this:
.h
#import <UIKit/UIKit.h>
#interface MyLabel : UILabel {
}
#end
.m
#import "MyLabel.h"
#implementation MyLabel
-(void)awakeFromNib {
UIFont *custom = [[UIFont alloc] init];
custom = [UIFont fontWithName:#"Chalkduster" size:18];
self.font = custom;
}
#end
Now select Your label in storyboard and go to indentity inspector and in Custom Class select created class above. Like this:
Output:
Note: Don't forget to release custom because You are allocating it.
Move the return self; three lines down. You return from the init method before you do your custom initialization.
Edit to reflect new information from comment:
When deserializing the view from a nib you also have to override initWithCoder:

UIImagePickerController delegate warning

I've just put a photo picker into my project, and everything works fine. The only thing is it insists on giving me the following warning where I set the delegate -
Assigning to 'id<UINavigationControllerDelegate,UIImagePickerDelegate>' from incompatible type 'AddTargetViewController *'
I have set up the delegate in the AddTargetViewController.h in the normal way -
#interface AddTargetViewController : UIViewController <UIImagePickerControllerDelegate>
and I can't see anything wrong. As I say, it works fine, and all the delegate methods fire off as they should.
-(void)takePhoto {
UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
imagePicker.delegate = self; // *** warning on this line ***
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
[self presentModalViewController:imagePicker animated:YES];
}
Thanks for any help!
This is duplicate question to iPhone - UIImagePickerControllerDelegate inheritance.
In short your view controller has to conform to UINavigationControllerDelegate in addition to UIImagePickerDelegate.
Along with your UIImagePickerControllerDelegate just add UINavigationControllerDelegate in your .h file and it should work fine.

Load nib from other nibs (i.e. Interface Builder) in Cocoa

I have a view setup in Interface Builder which contains a viewController that loads another Nib file. However, for some reason the objects contained in the nib file being loaded never gets called awakeFromNib. What am I missing here? Is there anyway to load views from Nib in interface builder and also manage their properties and sizing in the interface builder?
In general, what are the best practices for managing multiple nibs and composing them into complex views?
Final Solution:
I created a NSViewController subclass like this.
#interface NibLoadingViewController : NSViewController
// The placeholder would be replaced during run-time by the view
#property (weak, nonatomic) IBOutlet NSView *placeholder;
#end
#implementation NibLoadingViewController
#synthesize placeholder = _placeholder;
- (void)awakeFromNib {
if (self.placeholder)
self.view = self.view; // Trigger lazy loading
}
- (void)loadView {
[super loadView];
if (!self.view)
return;
// Replace the placehoder if it exists
if (self.placeholder) {
// Copy over relevant attributes
self.view.frame = self.placeholder.frame;
self.view.autoresizingMask = self.placeholder.autoresizingMask;
self.view.autoresizesSubviews = self.placeholder.autoresizesSubviews;
// Replaces the old view
[self.placeholder.superview replaceSubview:self.placeholder with:self.view];
self.placeholder = nil;
}
self.nextResponder = self.view.nextResponder;
self.view.nextResponder = self;
}
#end
This way, you just need to hook the placeholder outlet in the nib that contains the view controller and it will automatically load the other nibs for you and copy all the attributes from placeholder over and replace it in the main nib.
The content of the nib-file is lazy-loaded. If you want -(void)awakeFromNib to be called, you need to access something from the nib-file first.
NSViewController *controller = [[NSViewController alloc] initWithNibName:#"MyView" bundle:nil];
/*
* awakeFromNib was not called yet
*/
NSView *view = controller.view;
/*
* but now -(void)awakeFromNib was called.
*/

Custom delegate methods in a NSTextView subclass - compiler warnings

Long story short (please stop me if I'm doing this wrong): I want to have an NSTextView accept a custom drag type, and upon receipt of such a drag change the content to match.
To do this, I subclass NSTextView to implement the custom drag type, and (from the subclass) send a message to the NSTextView delegate when done. This works just fine, but I get a familiar compiler warning (though everything works fine):
Method '-dragReceivedWithTrack:' not found (return type defaults to 'id')
Some code:
#interface LyricTextView : NSTextView {
}
#end
#interface NSObject (CustomDragging)
-(BOOL)dragReceivedWithTrack:(NSDictionary *)track;
#end
#implementation LyricTextView
-(BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
NSData *data = [[sender draggingPasteboard] dataForType:kMyType];
NSDictionary *track = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if ([[self delegate] respondsToSelector:#selector(dragReceivedWithTrack:)]) {
return ([[self delegate] dragReceivedWithTrack:track]); // gives a warning, but works
}
return NO;
}
Shouldn't the informal protocol take care of the warning?
What am I doing wrong?
You have not declared a protocol, you have declared a category on NSObject. You could probably remove its definition without affecting the compiler warning.
Since you have a subclass, you are stuck with the delegate as it is (which is an id ).
To quelch the compiler warning, you should be able to simply cast it to id, like so:
id delegate = (id)[self delegate]
if ((delegate respondsToSelector:...]) {...}

Resources