Loading / creating views from NIB for GeoLocation - IOS and MapKit - ios

I have two classes - MapView and MapController. The main idea is to make View a shared object in MVC pattern.
MapView has IBOutlet "mapView" for MKMapView located in MapNib.xib
MapController contains property "mapView" referencing to class MapView
Then i try to set some properties of MKMapView from controller and it does not react on this anyway. For example i try in MapController :
self.mapView.mapView.showUserLocation = YES; // does not show blue point ...
MapView Class :
#interface MapView : UIViewController
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
...
//UINib *view = [UINib nibWithNibName:#"MapView" bundle:nil];
//[view instantiateWithOwner:self options:nil];
#end
MapController Class :
#interface MapController : UIViewController<
CLLocationManagerDelegate,
MKMapViewDelegate>
#property (nonatomic, retain) MapModel *mapModel;
#property (nonatomic, retain) MapView *mapView;
...
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView = [[[MapView alloc] init] autorelease];
self.mapView.mapView.showsUserLocation = YES;
} #end
I tried to make MapView a subclass of UIView, UINib, UIViewcontroller, tried to load NIB directly using UINib::nibWithNibName, UIViewController::initWithNibName, UIViewController::loadNibNamed - it does not matter ... i can see the map but blue point is not shown anyway ... why???
Only one combination works for me - to name NIB the same way as controller (MapController.xib) and add outlet for MKMapView as controller property ... it seems like it is impossible to load NIB / View in one class and use it in another, am i right?
Somehow this works fine :
#interface MapController : UIViewController
#property (nonatomic, retain) IBOutlet MKMapView *mapView; // NIB was renamed to MapController.xib
...
#end
And then in controller :
self.mapView.showUserLocation = YES; // now this shows blue dot ... why???
Thanks, Art

IBOutlets do not need to be created. The NIB creates them and assigns them to your vars, your are overwriting it by allocing and initing a new mapview and saving it to that variable

Related

exc_bad_access code=1 when loading UIView

I have an app where I need to present an overlay for feedback. I started by simply creating the exact thing I wanted within the UIViewController I wanted. However this presents to 2 problems. 1) I can't reuse this in another view (As I need to now) and 2) Because it's an overlay, it covers the entire UIViewController on the storyboard so I can't see the controls beneath it.
I looked at moving to an external UIView .xib file and loading dynamically which worked great, except whatever I did, I couldn't never get a handle on the labels within the nib to update the text.
Then I decided that making it a class and creating a delegate method for it would probably be the best way forward.
I have created a very simply .xib and laid it out as well as a .h and .m file (overlayView) and wired it all in an it looks good, except when trying to present the overlayView I get a exc_bad_access on the line
[window addSubview:self];
And I can't work out why. Full code below:
overlayView.h
#import <UIKit/UIKit.h>
#class overlayView;
#protocol overlayDelegate;
#interface overlayView : UIView
#property (nonatomic, strong) id <overlayDelegate> delagate;
-(instancetype)initWithTitle:(NSString *)title
dateFrom:(NSString *)dateFrom
dateTo:(NSString *)dateTo
description:(NSString *)description;
#property (strong, nonatomic) IBOutlet UILabel *overlayTitleLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDateFromLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDateToLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDescLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayIcon;
-(void)showOverlay;
-(void)dismissOverlay;
#end
#protocol overlayDelegate <NSObject>
#optional
#end
overlayView.m
#import "overlayView.h"
#import "NSString+FontAwesome.h"
#implementation overlayView
- (instancetype)initWithTitle:(NSString *)title dateFrom:(NSString *)dateFrom dateTo:(NSString *)dateTo description:(NSString *)description {
self.overlayViewTitleLbl.text = title;
self.overlayViewDateFromLbl.text = dateFrom;
self.overlayViewDateToLbl.text = dateTo;
self.overlayViewDescLbl.text = description;
self.overlayViewIcon.text = [NSString fontAwesomeIconStringForIconIdentifier:#"fa-calendar"];
return self;
}
-(void)showOverlay {
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview:self]; <-- Code causing issue
[window makeKeyAndVisible];
}
-(void)dismissOverlay {
// Not wired in yet
}
#end
The being called in my main view controller like:
overlay = [[overlayView alloc] initWithTitle:[tmpDict objectForKeyedSubscript:#"Title"] dateFrom:startDate dateTo:stopDate description:[tmpDict objectForKeyedSubscript:#"Desc"]];
[overlay showOverlay];
Any ideas why this doesn't want to play ball? I have breakpointed the initWithTitle method and all information is being passed correctly so I think I am very close to what I am trying to achieve.
you need to initiate your view first, you're returning self without initiating it
- (instancetype)initWithTitle:(NSString *)title dateFrom:(NSString *)dateFrom dateTo:(NSString *)dateTo description:(NSString *)description {
self = [super init];
if (self) {
self.overlayViewTitleLbl.text = title;
self.overlayViewDateFromLbl.text = dateFrom;
self.overlayViewDateToLbl.text = dateTo;
self.overlayViewDescLbl.text = description;
self.overlayViewIcon.text = [NSString fontAwesomeIconStringForIconIdentifier:#"fa-calendar"];
}
return self;
}

Initialising view controller with IBOutlets to custom views

I am trying to find a way to initialise a view controller which has IBOutlets to a custom view that I have created in a XIB.
Here is the code where I initialise my class:
MyContentViewController *pageContentViewController = [[MyContentViewController alloc] init];
self.pageContent = pageContentViewController;
[pageContentViewController view];
MyContentViewController has the following properties:
#interface MyContentViewController : UIViewController
#property (nonatomic, weak) IBOutlet MyContentView *topLeftView;
#property (nonatomic, weak) IBOutlet MyContentView *topRightView;
#property (nonatomic, weak) IBOutlet MyContentView *bottomLeftView;
#property (nonatomic, weak) IBOutlet MyContentView *bottomRightView;
In MyContentViewController xib I have 4 views which I have set as MyContentView and have hooked the IBOutlet's above to the views in the storyboard.
The custom view is defined as following:
#import <UIKit/UIKit.h>
#interface MyContentView : UIView
#property (nonatomic, strong) IBOutlet UILabel *labelView;
#end
However when I run the application, I get the 4 views I have added in the MyContentViewController xib. However none of them display the UILabel from the custom UIView.
I have added the following in MyContentView:
- (void)awakeFromNib {
NSLog(#"VIEW AWAKE");
}
This get printed out so the views are being loaded. However how can I get them to display using the 4 IBOutlets.
Here is a picture of the app running with the view. There is no labels on the 4 views:
I see that your "MyContentView" has a nib of it's own. Loading a custom UIView class which has a nib layout from another nib is a bit more complex.
I think this blog post contains the answer

MVC. Setting data in View

View does not know about the model. I have custom view:
#interface CustomView : UIView
#property UIImageView *imageView;
#property UILabel *labelView;
#property UILabel *dateLabelView;
#property UIImageView *badgeView;
...
#end
Set data in ViewController:
-(void)viewDidLoad
{
[super viewDidLoad];
...
//Install data from model in view
self.customView.labelView.text = self.model.title;
self.customView.badgeView.hidden = self.model.isBadge;
self.customView.dateLabelView.text = [self formatDate:self.model.createDate];
...
}
How to use CustomView in other ViewControllers, without having to copy code and or creating the following method in the class CustomView:
- (void)setData:(id)data;
because View does not know about the model.

iOS Custom View Text Labels Are Nil

Right now I have a custom view class called OTGMarkerDetailView which inherits from UIView and a corresponding .xib with it. It just has two text labels and I've linked the text labels to the text label IBOutlets in OTGMarkerDetailView.m.
OTGMarkerDetailsView.h:
#import <UIKit/UIKit.h>
#interface OTGMarkerDetailView : UIView
- (void)setLabelsWithMainAddress:(NSString *)mainAddress subAddress:(NSString *)subAddress;
#end
OTGMarkerDetailView.m
#import "OTGMarkerDetailView.h"
#interface OTGMarkerDetailView ()
#property (nonatomic, strong) IBOutlet UILabel *mainAddressLabel;
#property (nonatomic, strong) IBOutlet UILabel *subAddressLabel;
#end
#implementation OTGMarkerDetailView
- (void)setLabelsWithMainAddress:(NSString *)mainAddress subAddress:(NSString *)subAddress {
NSLog(#"%#", self.mainAddressLabel.text);
self.mainAddressLabel.text = mainAddress;
self.subAddressLabel.text = subAddress;
NSLog(#"%#", self.mainAddressLabel.text);
}
#end
I load it in another view as a subview, using initWithFrame. But the console always logs null when I try to set the text label values, and when I use a breakpoint it seems the mainAddressLabel and the subAddressLabel are nil themselves. Did I do something wrong in linking the xib to the view? What am I missing? Thanks.
I found a work around. I have created a custom UIView.
1.
I attached Nib file to it in initWithFrame method
CustomView *nibView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *array = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:nil];
nibView = [array objectAtIndex:0];
[self addSubview:nibView];
}
return self;
}
You can see clearly, I haven't created the instance of UIView instead I created nibView of the same class type.
2.
Now creating IBOutlet properties and work on it. In customView.m file.
#interface FTEndorsedExpandedView : UIView
#property (retain) IBOutlet UILabel *label;
#end
3.
Create functions to set title or changing properties. (in customView.m file). Use nibView to access the properties rather than using self.label
-(void)setLabelText:(NSString*)string{
[nibView.label setText:string];
}
When you create your custom view in another view using initWithFrame a new instance of your custom class is created. This instance is not the same one you have in interface builder and hence the label properties are nil for this newly created instance. In order to solve this problem either put your view in its parent view in interface builder with its connection attached or override initWithFrame for your custom view and initialise your labels in there.

iOS 5 create custom UIButton reusable component with .XIB

I'm newbie in the iOS development and I'm working in a projecte that it uses iOS5 and Storyboarding. I would like to create a reusable component, like a button, with a custom view (inside the button there will be some images and labels, it will be a big button), to create some of them in the same view of a Storyboard.
So I've created a XIB file (ItemClothes.xib) with a UIButton and inside of it some UIImagesViews and a UILabel. Then I've created a subclass of UIButton (UIItemClothes.h and UIItemClothes.m), with properties for UIImageViews and UILabel components.
UIItemClothes.h
#import <UIKit/UIKit.h>
#import "SCClothes.h"
#interface UIItemClothes : UIButton
#property (nonatomic, strong) IBOutlet UIImageView *imageClothes;
#property (nonatomic, strong) IBOutlet UIActivityIndicatorView *loadingImage;
#property (nonatomic, strong) IBOutlet UIImageView *seasonIconClothes;
#property (nonatomic, strong) IBOutlet UIImageView *categoryIconClothes;
#property (nonatomic, strong) NSString *idClothes;
#property (strong, nonatomic) IBOutlet UILabel *lblProva;
#end
UIItemClothes.m
#import "UIItemClothes.h"
#implementation UIItemClothes
#synthesize imageClothes = _imageClothes;
#synthesize loadingImage = _loadingImage;
#synthesize seasonIconClothes = _seasonIconClothes;
#synthesize categoryIconClothes = _categoryIconClothes;
#synthesize idClothes = _idClothes;
#synthesize lblProva = _lblProva;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:#"ItemClothes" owner:self options:nil] objectAtIndex:0]];
}
return self;
}
#end
Then in the .XIB file I've set the class of UIButton as UIItemClothes, and make the relationships between XIB's UI components and my class properties.
So, after that, in the Storyboard, in the ViewController of one view I've written this code:
UIItemClothes *item = [[UIItemClothes alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 200.0)];
item.lblProva.text = #"test!";
[item.categoryIconClothes setImage:iconCategory];
item.seasonIconClothes.image = iconSeason;
[cell addSubview:item];
As you see, this component will be inside a TableViewCell, and the idea is to put more components (UIItemClothes) inside of it.
The problem is that the component is drawed but any outlet is set as I do in the code above.
Can anyone help me?
Thanks!
well, the problem has been resolved... Instead of having a custom subclass of UIButton, there will be needed a ViewController with all Outlets. Then in the other ViewController (StoryBoard) is initialized this new ViewController

Resources