UICollectionViewWaterfallLayout - How to setup properties and delegate - properties

in the latest issue of iOS Dev Weekly there was an interesting article about the UICollectionWaterfallLayout: https://github.com/chiahsien/UICollectionViewWaterfallLayout
As you see, there are 2 steps to be performed in order to get working the sample app. But, because I'm a newbie in Objective-C and iOS development I get stuck in these steps.
In particular:
Step 1: What does it mean setup those 3 properties and 1 delegate? I know what properties and delegates are, but equally I don't know what to do.
Step 2: How can I implement that method in my delegate?
Sorry for the obvious questions. I'm studying on the Big Nerd Ranch book but I'm still in trouble with this platform.
Thanks all in advance.

This is just a "layout", which means you also need to provide a viewController and a collectionView by yourself, then wrap these 3 things up!
Here is an example:
In your WaterfallViewController.h
#import "UICollectionViewWaterfallLayout.h"
#interface WaterfallViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate, UICollecitonViewDelegateWaterfallLayout>
#property (nonatomic, strong) UICollectionView *collectionView;
#end
And in your WaterfallViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewWaterfallLayout *layout = [[UICollectionViewWaterfallLayout alloc] init];
layout.delegate = self;
layout.columnCount = 2;
layout.itemWidth = 146;
layout.sectionInset = UIEdgeInsetsMake(9, 9, 9, 9);
_collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
_collectionView.dataSource = self;
_collectionView.delegate = self;
_collectionView.showsVerticalScrollIndicator = NO;
_collectionView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[_collectionView registerClass:[MyCell class] forCellWithReuseIdentifier:#"MyCell"];
[self.view addSubview:self.collectionView];
}
#pragma mark - UICollecitonViewDelegateWaterfallLayout Delegate
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewWaterfallLayout *)collectionViewLayout
heightForItemAtIndexPath:(NSIndexPath *)indexPath
{
// return the height for cell at indexPath.
}
Sorry for the inconvenient, I'll add some sample codes to the repo soon.

Related

NSArrayController bound to NSCollectionview

I'm kinda new into bindings, somehow prevented it. But I want to use them now.
Talking about OSX and this is programmed in code not in IB.
So, I have data coming from CoreData into my ArrayController. A NSCollectionView is bound to this arraycontroller and if there is data, this binding works the data is displayed.
But, each item has some buttons, sliders, textfields. On a click, a code will change the tag or value of those things. I thought it is enough when I send the change to coredata and save it. Shouldnt the arraycontroller get this and update my items in the collectionview?
Because the tags(first thing I tried) dont get updated if its updated in coredata.
Do those fields have to be somehow bound?
the tag is set in a subclass of NSCollectionViewItem this way:
[[(BEItem *)[self view] valueSlider] setTag:[[representedObject itemTag] intValue]];
Is there anything I have to tell the CollectionView to update itself and take the new data from the controller?
Thanks
Benjamin
EDIT
I have changed my collectionview. I read it isnt really possible to bind a representable object and in the answer below, it is bound to some property, but this property isnt updated either. Then I read about newItemForRepresentedObject that you should use this function. Now, I created everything like shown below, but the program is always crashing after 10 seconds or something and nothing is displayed. It is continuously calling setChannelID, but never setting the ID to the property. Because of that it is always called I think this is the problem. (The if gets never to only return)
What is the problem here? Im really confused by the collectionview by now.
And this is just code, nothing in IB.
Setting up the View in appdelegate:
NSCollectionViewItem *testitem = [[NSCollectionViewItem alloc] init];
[testitem setView:[ChannelView new]];
self.collectionView = [[ChannelCollectionView alloc] initWithFrame:NSMakeRect(10, 0, mixerWidth, self.splitview.frame.size.height)]; // initWithFrame:[[[self window] contentView] frame]
[self.collectionView setItemPrototype:testitem];
[self.collectionView setMaxNumberOfRows:1];
[self.collectionView setAutoresizingMask:(NSViewMinXMargin | NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin | NSViewHeightSizable| NSViewMaxYMargin)];
[self.collectionView setAutoresizesSubviews:YES];
[self.collectionView bind:NSContentBinding toObject:self.channelController withKeyPath:#"arrangedObjects" options:nil];
ChannelView:
#import <Cocoa/Cocoa.h>
#interface ChannelView : NSView
#property (readwrite, nonatomic, copy) NSString *channelName;
#property (readwrite, nonatomic, copy) NSNumber *channelID;
#property (readwrite) NSTextField *channelNameField;
#property (readwrite) NSTextField *deviceChannelField;
#end
#implementation ChannelView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:NSMakeRect(0, 0, 300, 500)];
if (self) {
// Initialization code here.
ColorView *test = [[ColorView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
self.channelNameField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)];
self.deviceChannelField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 50, 100, 20)];
[self addSubview:test];
[self addSubview:self.channelNameField];
[self addSubview:self.deviceChannelField];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
//add die teile
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
}
// setters.
-(void)setChannelID:(NSNumber *)chanID
{
//NSLog(#"hallo");
if (self.channelID == chanID) {
return;
NSLog(#"da");
}
else {
NSLog(#"hello"); //just this in debug output
self.channelID = [chanID copy];
NSLog(#"no output");
// self.channelID = chanID;
NSLog(#"chanid %d current: %d", chanID.intValue, self.channelID.intValue); //never shown in debug
[self.deviceChannelField setStringValue:[NSString stringWithFormat:#"%d",self.channelID.intValue]];
}
}
#end
And this piece in my subclasses NSCollectionView
- (NSCollectionViewItem *)newItemForRepresentedObject:(ChannelsToMixes*)object
{
NSCollectionViewItem *item = [super newItemForRepresentedObject:object];
// ChannelView *view = (ChannelView *)[item view];
NSLog(#"cahnnelid: %d",object.channelID.intValue);
// [view bind:#"title" toObject:object withKeyPath:#"title" options:nil];
[item.view bind:#"channelID" toObject:object withKeyPath:#"channelID" options:nil];
//NSLog(#"test");
//NSLog(#"%#",object);
return item;
}
If anyone knows why the setter isnt setting the property give me a tip :)
It should be able to do this and is not released or anything, at least that I know of (using ARC)
Yes, you have to bind the value of your slider to your CollectionViewItem.
You can either do this in code with this method:
-bind:toObject:withKeyPath:options:
Which would look in your example like this:
[[(BEItem *)[self view] valueSlider] bind:#"tag" toObject:self withKeyPath:#"itemTag" options:nil];
Or, if you use IB, in the InterfaceBuilder by setting the value to bind to your Colletion View Item representedObject.itemTag

EXC_BAD_ACCESS when dragging UIScrollView

In a controller I'm creating a UIScrollView. I'm trying to set this viewcontroller as the UISCrollview delegate and to implement the delegate's method in order to add (later) a UIPageControl.
I've read a bit, and found this link, this other link and other here on SO, and some useful tutorial all around the web, but I don't understand what I'm doing wrong. Everytime a scroll the UIScrollView, the app crashes with an EXC_BAD_ACCESS error.
Here's my .h file
#import <UIKit/UIKit.h>
#interface StatsViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *scrollView;
UIPageControl *pageControl;
}
#end
Then in my .m file, I'm creating the scrollview and trying to define the delegate method like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSInteger boxWidth = self.view.frame.size.width;
NSInteger boxHeight = 412;
scrollView = [ [UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, boxHeight)];
scrollView.pagingEnabled = TRUE;
scrollView.delegate = self;
NSInteger numberOfViews = 2;
StatBreatheCounter *breatheCounter = [ [StatBreatheCounter alloc] init];
breatheCounter.view.frame = CGRectMake(0, 0, boxWidth, boxHeight);
[scrollView addSubview:breatheCounter.view];
BreatheLocationViewController *breatheLocation = [ [BreatheLocationViewController alloc] init];
breatheLocation.view.frame = CGRectMake(320, 0, boxWidth, boxHeight);
[scrollView addSubview:breatheLocation.view];
scrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, boxHeight);
[self.view addSubview:scrollView];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
NSLog(#"RUNNING");
}
...but every time I slide on the scroll view, the app is crashing.
Now, I'm quite a n00b on Ojective-C, but I feel I'm missing something. Browsing around everything points on the fact that the delegate could be deallocated early, and when the user trigger the action, no one is handling the method (sorry for the explanation :)).
...but if the delegate it's the viewcontroller itself, how could it be deallocated?
As you can see, I'm quite confused :(
Any help would be really appreciated
--
EDIT:
I'm going to include here the solution founded thanks with your comments and answer.
When I posted my question I was so convinced that the error was coming from the way I was creating the UIScrollView and setting its delegate that I didn't realize that the problem was (as everything was suggesting, btw :)) I was allocating the StateViewController in its parent without declaring any "strong" reference to it (again, sorry for the explanation, I'm really a n00b in this).
Thanks a lot for your helping in pointing me on the right direction
It looks like you are losing reference to the delegate during scroll. I would look into any other release events around StatsViewController or other events that could cause it to be dereferenced.

iPad custom/dynamic layout

I am a newbie to iOS development. I have gone through a couple of tutorials and know the basics, but currently I am stuck on how to proceed further. I am planning to create an app for basic home automation (i.e. switching lights, measuring temperature etc.). The backend is all set, so this is just about the frontend. This is what I am planning to do:
The main view of the app should display a floor plan or the layout of the house
On this floor plan you should be able to add lights/sensors/etc. - lets say objects to keep it generic
These objects should be draggable so that you can arrange them on the floor plan according to where they really are (physically) - ideally this drag mode is toggable similar to rearranging icons on the home screen
Each object should have a popover view (i.e. to set the dimmer intensity, switch lights etc.)
I know there is a lot of work to do, but I don't really know how to set this up. Current alternatives:
Create a custom UIView subclass that contains all the logic an do the drawing in custom code, i.e. the dragging, the popover positioning etc. - but I have the feeling that I wouldn't really be leveraging the iOS framework capabilities
Display the floor plan as an UIImageView and one UIButton for each object. This has the advantage that I can use StoryBoard to do the layouting and wiring (i.e. create segues for popovers etc.) - but I simply can't figure out how to do this with a variable number of buttons (since I don't know in advance how many buttons there will be). Is there some way to create these buttons in code?
Use a custom UITableView. I have seen a couple of examples where they seem to use table views even if the layout has nothing to do with tables (like in my example) but I haven't found any tutorials that explain this concept in more detail
Or am I totally on the wrong track? Any input is appreciated.
Thanks
D.
UPDATE:
After some more research and thought on this I think the way to go with iOS 6 is to use an UICollectionView with a custom layout. Once I have come up with a complete solution I will post it here. For older iOS versions I think it would be promising to go with Option Nr. 2 - i.e. creating each UIButton (for the automation objects e.g. lights) in code and having a custom UIView subclass to do the layouting of these buttons.
Ok I think UICollectionView is ideal for this usage scenario and I am just lucky to have started with iOS programming just as it was introduced to the framework. The following example is a UICollectionView that displays its elements according to their inherent coordinates. This example could also be applied to positioning objects on a map. I couldn't find any examples elsewhere so I'll post the main steps here (since I am a beginner please correct any mistakes).
To start off I created a simple project with one view and storyboard in XCode. I removed the standard view and inserted a Collection View Controller instead and configured my UICollectionViewController subclass as the class that should be used (in the properties of the controller in storyboard).
For the demo just set the background of the default UICollectionViewCell to a color and set the Identifier to "AutomationCell" for this example (if you change it be sure to adjust the code below).
First I create a simple object with some properties that represents an object that should be displayed on the floor plan:
#interface AULYAutomationObject : NSObject
#property NSString *title;
#property CGPoint position;
#end
Then I need my own delegate as subclass to the standard UICollectionViewDelegate since my custom UICollectionViewLayout will not have direct access to the dataSource objects. Therefore I provide a method that will give me the position of the object:
#protocol AULYAutomationObjectLayoutDelegate <UICollectionViewDelegate>
- (CGPoint)getPositionForItemAtIndexPath:(NSIndexPath *)indexPath;
#end
Make sure to implement this protocol in your controller like this:
#interface AULYViewController : UICollectionViewController <AULYAutomationObjectLayoutDelegate>
Then I implemented the standard datasource and delegate methods along with my custom one in the view controller subclass:
#interface AULYViewController ()
#property NSArray *objects;
#property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
#end
#implementation AULYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Set up the data source
NSMutableArray *automationObjects = [[NSMutableArray alloc] initWithCapacity:10];
// add some objects here...
self.objects = [automationObjects copy];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
[self.collectionView addGestureRecognizer:longPressRecognizer];
}
#pragma mark - UICollectionViewController
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.objects.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
AULYAutomationObjectViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AutomationCell" forIndexPath:indexPath];
// If you have a custom UICollectionViewCell with a label as outlet
// you could for example then do this:
// AULYAutomationObject *automationObject = self.objects[indexPath.row];
// cell.label.text = automationObject.title;
return cell;
}
#pragma mark - AULYAutomationObjectLayoutDelegate
- (CGPoint)getPositionForItemAtIndexPath:(NSIndexPath *)indexPath
{
AULYAutomationObject *automationObject = self.objects[indexPath.item];
return automationObject.position;
}
In a real project you would probably do some conversion from the object model position to the position on screen (e.g. GPS data to pixels) but here this is left out for simplicity.
After having done that we still need to set up our layout. This has the following properties:
#interface AULYAutomationObjectLayout : UICollectionViewLayout
#property (nonatomic, strong) NSIndexPath *draggedObject;
#property (nonatomic) CGPoint dragPosition;
#end
And the following implementation:
#implementation AULYAutomationObjectLayout
- (void)setDraggedObject:(NSIndexPath *)draggedObject
{
_draggedObject = draggedObject;
[self invalidateLayout];
}
- (void)setDragPosition:(CGPoint)dragPosition
{
_dragPosition = dragPosition;
[self invalidateLayout];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
id viewDelegate = self.collectionView.delegate;
if ([viewDelegate respondsToSelector:#selector(getPositionForItemAtIndexPath:)])
{
CGPoint itemPosition = [viewDelegate getPositionForItemAtIndexPath:indexPath];
layoutAttributes.center = itemPosition;
layoutAttributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
}
if ([self.draggedObject isEqual:indexPath])
{
layoutAttributes.center = self.dragPosition;
layoutAttributes.transform3D = CATransform3DMakeScale(1.5, 1.5, 1.0);
layoutAttributes.zIndex = 1;
}
return layoutAttributes;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [[NSMutableArray alloc] initWithCapacity:4];
for (NSInteger i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
[allAttributes addObject:layoutAttributes];
}
return allAttributes;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
- (CGSize)collectionViewContentSize
{
return [self.collectionView frame].size;
}
#end
To set the custom layout in the storyboard just go to the properties of the controller view and select custom as the layout type - then select your custom class.
Now to enable drag and drop support with the long press gesture simply add the following to your controller:
- (void)handleTapGesture:(UITapGestureRecognizer *)sender
{
AULYAutomationObjectLayout *automationLayout = (AULYAutomationObjectLayout *)self.collectionView.collectionViewLayout;
if (sender.state == UIGestureRecognizerStateBegan)
{
CGPoint initialPinchPoint = [sender locationInView:self.collectionView];
NSIndexPath* tappedCellPath = [self.collectionView indexPathForItemAtPoint:initialPinchPoint];
[self.collectionView performBatchUpdates:^{
automationLayout.draggedObject = tappedCellPath;
automationLayout.dragPosition = initialPinchPoint;
} completion:nil];
}
else if (sender.state == UIGestureRecognizerStateChanged)
{
automationLayout.dragPosition = [sender locationInView:self.collectionView];
}
else if (sender.state == UIGestureRecognizerStateEnded)
{
AULYAutomationObject *automationObject = self.objects[automationLayout.draggedObject.item];
automationObject.position = [sender locationInView:self.collectionView];
[self.collectionView performBatchUpdates:^{
automationLayout.draggedObject = nil;
automationLayout.dragPosition = CGPointMake(0.0, 0.0);
} completion:nil];
}
}
One important note:(this cost me at least an hour): When using the transform3D you should make sure to import QuartzCore into your linked frameworks (in the project properties below the orientation settings). Otherwise you will get a Mach-O Linker Error saying that _CATransform3DMakeScale can not be found.

Why isn't my subclassed UItableView scrolling?

I'm writing an iOS 5 app (in Xcode 4.3, using Storyboards and ARC) that has some table cells that need to respond to horizontal pans. I had a table setup that worked really well but then I needed to implement the same behavior on another scene. I figured the best-practices way would be to abstract out the gesture-recognizing and -handling code into subclasses. But now the tableView won't scroll, and the solution I had for this problem under the old method doesn't help.
I have a RestaurantViewController which inherits from UIViewController and has a property ULPanningTableView *tableView. Some of the table's cells are MenuItemCells and inherit from ULPanningTableViewCell. The table's delegate and data source are the RestaurantViewController.
ULPanningTableViewCell inherits from UITableViewCell and is pretty close to the original, the only difference being that it has properties to keep track of the cell's front and back views, and the custom backgrounds.
ULPanningTableView is a bit more complicated, since it has to set up the recognition and handling.
ULPanningTableView.h:
#import <UIKit/UIKit.h>
#interface ULPanningTableView : UITableView <UIGestureRecognizerDelegate>
#property (nonatomic) float openCellLastTX;
#property (nonatomic, strong) NSIndexPath *openCellIndexPath;
- (id)dequeueReusablePanningCellWithIdentifier:(NSString *)identifier;
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer;
// ... some helpers for handlePan:
#end
and ULPanningTableView.m:
#import "ULPanningTableView.h"
#import "ULPanningTableViewCell.h"
#implementation ULPanningTableView
#synthesize openCellIndexPath=_openCellIndexPath, openCellLastTX=_openCellLastTX;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#pragma mark - Table View Helpers
- (id)dequeueReusablePanningCellWithIdentifier:(NSString *)identifier
{
ULPanningTableViewCell *cell = (ULPanningTableViewCell *)[self dequeueReusableCellWithIdentifier:identifier];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panGestureRecognizer setDelegate:self];
[cell addGestureRecognizer:panGestureRecognizer];
return cell;
}
#pragma mark - UIGestureRecognizerDelegate protocol
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// for testing: only allow UIScrollViewPanGestureRecognizers to begin
NSString *gr = NSStringFromClass([gestureRecognizer class]);
if ([gr isEqualToString:#"UIScrollViewPanGestureRecognizer"]) {
return YES;
} else {
return NO;
}
}
#pragma mark - panhandling
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer
{
// ...
}
// ... some helpers for handlePan:
#end
I've played around with gestureRecognizerShouldBegin:, because that was how I solved this problem back when these weren't separate classes (ULPanningTableView stuff was implemented inside RestaurantViewController and ULPanningTableViewCell was stuff was implemented in MenuItemCell. I would essentially return NO for gestures where the translationInView was more vertical than horizontal). Anyway, I can't get the table to scroll! I can get the pan gestures to be recognized if I return YES from gestureRecognizerShouldBegin:, or if I remove the UIGestureRecognizerDelegate implementation entirely.
I'm still a beginner in iOS, and in Objective-C, so I only have hunches based on things I've read, and I'm under the impression from a similar problem that the culprit is UIScrollViewPanGestureRecognizer doing voodoo with the responder chain...
I would greatly appreciate any light you can shed on this!
Ok, so I feel really silly. -handlePan: is already a method! I changed it to -handleCustomPan: and it will handle other pans normally. I'm not sure why it wasn't crashing, but there it is. Oh, and I had to keep the UIScrollViewPanGestureRecognizer edge case in -gestureRecognizerDidBegin::
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
NSString *gr = NSStringFromClass([gestureRecognizer class]);
if ([gr isEqualToString:#"UIScrollViewPanGestureRecognizer"]) {
// allow scroll to begin
return YES;
} else if ([gr isEqualToString:#"UIPanGestureRecognizer"]){
UIPanGestureRecognizer *panGR = (UIPanGestureRecognizer *)gestureRecognizer;
// allow horizontal pans to begin
ULPanningTableViewCell *cell = (ULPanningTableViewCell *)[panGR view];
CGPoint translation = [panGR translationInView:[cell superview]];
BOOL should = (fabs(translation.x) / fabs(translation.y) > 1) ? YES : NO;
if (!should) {
[self closeOpenCellAnimated:YES];
}
return should;
} else {
NSLog(#"%#",gestureRecognizer);
return NO;
}
}

How to pass a String from one .m to another .m file

(sorry for the bad english, im from germany)
Im sorry, Im relativ new in XCode and also in objective C.
I have been searching for my problem for a long time, even here, but I didnt found the answer. I belive it is very easy, but it wont work in my projects :-(
The Problem ist, I would like to use a string in in two .m files.
For example, if I create a utility app. There will be a mainview and a flipside view. both have one .h file and one .m file.
Now I want to Fill a String in the mainview with content of a textfield, and if i switch the view, the content of the string from the main view, should be shown in a textfield on the flipside view.
I have read about propertys, synthesize... but I dont understand it. :-(
Please Please help me :-(
Shortly: I want to use one String in two .m files, so I can work with the content in both .m files, and even in both xib files.
I hope someone can help me.
regards Dennis
#import "MainViewController.h"
#import "MyFirstAnnotation.h"
#implementation MainViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)annosetzen:(id)sender{
CLLocationCoordinate2D coor;
coor.latitude = 54.3327162876622;
coor.longitude = 10.1518177986145;
MKCoordinateSpan span;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
MKCoordinateRegion region;
region.center = coor;
region.span = span;
MyFirstAnnotation *anno = [[MyFirstAnnotation alloc] init];
[mapView addAnnotation:anno];
[mapView setRegion:region animated:TRUE];
//MKReverseGeocoder *revGeo = [[MKReverseGeocoder alloc] initWithCoordinate:coor];
//revGeo.delegate = self;
//[revGeo start];
}
#import "MyFirstAnnotation.h"
#implementation MyFirstAnnotation
- (CLLocationCoordinate2D)coordinate {
CLLocationCoordinate2D coor;
coor.latitude = 54.3327162876622;
coor.longitude = 10.1518177986145;
return coor;
}
- (NSString *)title {
return #"Name"; //This should be set from main view controller
}
- (NSString *)subtitle {
return #"Sub"; //This also
}
#end
Now if I change the #"Name" and #"Sub" in NSStrings, how can I pass them a value from main view controller?
When your MainViewController creates the FlipSideViewController, it can give it the string in question. If your FlipSideViewController and MainViewController both have a someString property, do this in your MainViewController:
self.flipSideViewController = [[FlipSideViewController alloc] initWithNibName:nil bundle:nil];
flipSideViewController.someString = self.someString;
[self.navigationController pushViewController:flipSideViewController animated:YES];
Then, when your main view controller is about to become visible again (such as in its -viewWillAppear):
if (self.flipSideViewController) {
self.someString = self.flipSideViewController.someString;
self.flipSideViewController = nil;
}
This is just one way to do it, of course. Another way would be to make the main controller the delegate of the flip side controller, and have the flip side controller send it a message when someString changes.