iOS 7. A bug with frame on pushing of UITableViewController manually? - ios7

I use the following code:
PBComboBoxDetailsTableViewController *vc = (PBComboBoxDetailsTableViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"PBDetailListViewController"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"plist"];
NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:path];
vc.dataSource = settingsDict[#"Frequency"];
[self presentViewController:vc animated:YES completion:nil];
And UITableView appears under the status bar and of course I cannot set up its frame manually because it appears as a top view controller and position option is disabled.
Are there ways to solve this problem except of inserting this table into viewcontroller?

If your view controller is of type UITableViewController the view property of this controller, i.e. the top view in the hierarchy is the table view.
If you want your table view to fill any other space than the entire view (screen) you will have to use a UIViewController and add tableView, as well as its delegate and datasource methods manually.

Related

Xcode How to pass data from one UIviewController to another UIview Subview

I have a UIViewController (Main VC) into which another UIView is loaded as subview when a button is tapped on MainViewController. Actually I load a map view as subview in the main view controller. For that purpose I need to pass the coordinate from MainViewController to the subview (map view) to create the annotation there & then loaded inside the MainViewController.
In MainViewController the following method loads the subview correctly:
-(IBAction)showUserLocation{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"UserCurrentLocationView" owner:self options:nil];
UIView *currentLocationView = [nib objectAtIndex:0];
currentLocationView.frame = CGRectMake(8, 10, currentLocationView.frame.size.width, currentLocationView.frame.size.height);
[thirdPortion addSubview:currentLocationView]; // thirdPortion is a View Outlet in the Main VC wh
}
Here I want to pass a coordinate (lat/lon) to the UserCurrentLocationView 's class so that it can prepare the map and I can see the pointed map in the MainViewController when showUserLocation method is called by a button.
What is the way to set the value of a property that stays on the UIView (Subview) from the MainViewController.
Thanks in advance!
You have to subclass the UIView (I will call it YourView) and add a two properties for long and lat. Then put it as the class for your .xib - file named UserCurrentLocationView.
Then you do the following to set the variables.
-(IBAction)showUserLocation{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"UserCurrentLocationView" owner:self options:nil];
YourView *currentLocationView = (YourView *)[nib objectAtIndex:0];
currentLocationView.lon = self.fooValue;
currentLocationView.lat = self.fooValue2;
currentLocationView.frame = CGRectMake(8, 10, currentLocationView.frame.size.width, currentLocationView.frame.size.height);
[thirdPortion addSubview:currentLocationView]; // thirdPortion is a View Outlet in the Main VC wh
}

Add view to the top view controller

Im trying to add a UIView to the UIView that is currently showing.
This is the code I've come up with:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UINavigationController *nav = window.rootViewController;
UIViewController *viewController = [[nav viewControllers]lastObject];
NSLog(#"La clase: %#", [viewController class]);
[viewController.view addSubview:self.infoMsg];
The problem is that I dont see that UIView, the value of the variable viewController is correct, but I don't see the view added on that view...
Thanks
[EDIT]
I just checked and If for example instead of add as a subview infoMsg which is a UIView that I have syntesized, and I add a UIView that I create just before adding it adds correctly why is that? why can't I add an attribute of my object?
You have to still create the view before adding it, no matter if it's a property or just a local variable. I don't see where you initialize self.infoMsg. It's probably nil.
Try this:
NSLog(#"%#", self.infoMsg == nil ? #"It's nil" : #"It's not nil");
If it's nil, that that's your problem.

Use xib without a view controller

I need to create several similar views
In a easy way,I create some views in xib(each full screen)
And I have a view controller to use this xib's views,code like this:
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"MyXibName" owner:nil options:nil];
[self.view addSubview:[views objectAtIndex:aIndex]];
At this moment,view shows alright.
Now,there's some buttons in those views,so I connect a outlet for each view
bad thing happened
app crashed due to
uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x969db50> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key
Analyse:
Although my xib file's "File Owner" has been set,but there's no connection between xib and the only view controller.
How could I get the pointer of a view's button?
You can do it like this:
NSNib* aNib = [[NSNib alloc] initWithNibNamed:#"MyGreatNib" bundle:nil];
NSArray* topLevelObjs = nil;
for (SomeClass *obj in myOwnerObjects) {
topLevelObjs = nil;
if (![aNib instantiateNibWithOwner:obj topLevelObjects:&topLevelObjs])
{
NSLog(#"Warning! Could not load nib file.\n");
return;
}
for (id topLevelObj in topLevelObjs) {
if ([topLevelObj isKindOfClass:[NSView class]]) {
NSView *otView = (NSView *)topLevelObj;
// set frame...
[self addSubview:otView];
}
}
}
Oops...
I just found something.
UINib* xib = [UINib nibWithNibName:#"MyXibName" bundle:nil];
UIView* view = [[xib instantiateWithOwner:self options:nil] lastObject];
It works!
You can design xib as per your need by defining class UIView
Code in .m file:
NSArray* objects = [[NSBundle mainBundle] loadNibNamed:#"Interface" owner:nil options:nil];
UIView* mainView = [objects objectAtIndex:0];
for (UIView* view in [mainView subviews]) {
if([view isKindOfClass:[UILabel class]])
{
UILabel* label = (UILabel*)view;
//....As You Wish...
}
}
Default implementation of -loadView creates the view or loads NIB. As far as I know, there is no way to know the final size of the view at time of creation in -loadView. So the default view size is set to [[UIScreen mainScreen] bounds]. This is because it may be difficult to work work with zero frame view in -viewDidLoad and other methods.
Your one-line implementation may look like this:
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
You don't need to set the autoresizing mask, because you don't know in what context the view will be displayed. The caller is responsible to set you correct frame, autoresizing mask and similar external attributes (I call them like this).
Imagine this in a UINavigationController method:
// we are pushing new VC, view is accessed for the first time
pushedVC.view.frame = CGRectMake(...);
It is setting the correct frame, but your -loadView is called just before that -setFrame:. So during -viewDidLoad you have temporary non-zero frame, just to be able to setup subviews and internal autoresizing. After this, the correct frame is set to you and in -viewWillAppear: you have final frame.

Making an UILabel appear in another view once pressed in one view

I have 2 views
SoundViewController
ShowViewController
The sound view has a sound on it (IBAction).
- (IBAction)oneSound:(id)sender; {
if (oneAudio && oneAudio.playing) {
[oneAudio stop];
[oneAudio release];
oneAudio = nil;
return;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"1k" ofType:#"mp3"];
if (oneAudio) [oneAudio release];
NSError *error = nil;
oneAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
oneAudio.delegate = self;
[oneAudio play];
mainText.text =#"test";
}
And the ShowViewController needs to display the uilabel thats been pressed from the sound button
I want it so once the user has pressed the sound on SoundViewController, the uilabel appear on the showviewcontroller as it appear on the soundviewcontroller at the moment
Well, you can do this by
retain the UILabel
remove it from it's superview
add it to the other view
release it
You'll need access to the ShowViewController from the SoundViewController. So you'll have to define a connection between the two views (via IBOutlet or retained property, most likely).
I'm not sure what variable in the above code is your UILabel, so replace 'sender' with the correct ivar (mainLabel, maybe?):
[sender retain];
[sender removeFromSuperview];
[showViewController.view addSubview:sender];
[sender release];
Edit:
To clarify, the variable in the above code "sender" is the object that triggered this method. Whatever you have connected to the IBAction in the nib. In this case it would probably be a UIButton. You probably have to add an IBOutlet for your UILabel, and attach it to the correct UILabel in your nib file and use that IBOutlet in place of "sender".
You should probably read up on view hierarchy and view controllers. What you're trying to do is remarkably easy, and there are about a dozen ways to make it happen, but you have to understand how to structure your app correctly first. The most obvious issue is that the two view controllers need to have a reference to each-other in order to pass views back and forth. I can't send a view to another view if I don't know where that other view is. The views can be connected in IB, in code when they are created, etc.
view is a property of UIViewController. Assuming your ShowViewController is a subclass of UIViewController, it will have a view property. Perhaps your showViewController ivar isn't correctly typed? (if the type is id for example, it will give a warning when you try to access it's view property).

addSubview displays black screen with no content - iPhone

When I load my xib: AboutViewController as a subview of the view contentView, I just get a blank black screen, can someone help??
UIView* moreView = [[[NSBundle mainBundle] loadNibNamed:#"AboutViewController" owner:self options:nil] lastObject];
[_revealView.contentView addSubview:moreView];
You should use view controllers instead, then just access the view of the view controller:
UIViewController * aboutVC = [[UIViewController alloc] initWithNibName:#"AboutViewController" bundle:nil];
[_revealView.contentView addSubview:aboutVC.view];
Alternatively, you may be interested in presenting the view modally:
[_revealView.contentView.viewController presentModalViewController:aboutVC
animated:(BOOL)animated];
If you are not using ARC, you will have to manage aboutVC manually with retain and release.