I have a very curious case (similar to this one):
I have a simple UITextView which is located in a UIView which I load programatically (NIB). Contents are loaded from a TXT file into the UITextView.text. This happens in the viewDidLoad.
Everything is fine if my text is only a couple of lines and if there is no need for scrolling. If the text is longer than the UITextView, however, the text will NOT BE DISPLAYED. Only if I touch the screen and try to scroll, will the text suddenly pop up.
I tried this nudge to get the text appear in the viewDidLoad:
textView.contentOffset = CGPointMake(0.0, 1.0);
textView.contentOffset = CGPointMake(0.0, 0.0);
But it won't work. I also made sure to call [super viewWillAppear] etc., but again, no luck. The only thing which helps a bit is if I init my view and load the text in the viewDidAppear. However, the last part of the UITextView is still not shown unless I scroll.
Any ideas why the UITextView is behaving this way? I have no clue and would be grateful for any suggestions as this is holding me up for days now.
EDIT:
I now know what is causing this strange behaviour, but I still don't know why this can be. The ViewController in which the PageView will be displayed is animated into view (simple animation block to slide the viewController into the screen). If I take away the animation, everything is fine. I have no idea why, though.
Here is a bit more code (not sure if it helps to clarify). This is the viewController where I init the view.
- (void)viewDidLoad {
[super viewDidLoad];
if (self.currentPageView == nil) {
NSLog(#"createPage...");
PageView *cpv = [[PageView alloc] init];
self.currentPageView = cpv;
[cpv release];
[self.view addSubview:currentPageView.view];
}
[self loadContentsFromTXTFile];
[currentPageView setTitle:title
date:date
text:text ];
}
This is the init of the PageView class:
-(id)init {
//self = [super initWithNibName:nil bundle:nil];
self = [super initWithFrame:CGRectZero];
if (self) {
[[NSBundle mainBundle] loadNibNamed:#"PageView" owner:self options:nil];
[self addSubview:self.view];
}
return self;
}
-(void)setTitle:(NSString *)title date:(NSString *)date text:(NSString *)text {
UILabel *mytitle = [self titleOfPage];
[mytitle setText:title];
UILabel *mydate = [self dateOfPage];
[mydate setText:date];
UITextView *mytext = [self textOfPage];
[mytext setText:text];
}
Ok, I solved this by simply using a UINavigationController to handle the views in which the problematic UITextView was found. I still don't understand why this has caused problems, but if you experience this problem, there may be something wrong with the structure of your UIViewControllers and the way they refresh (or don't refresh) the UITextView.
Related
learning much from you guys, and after a few hours I finally managed to load a xib into a GRect for a search xib that I built.
Basically, when you tap a cell in main.xib, it loads search.xib in a Grect so that I can filter down a list, click o nthe value, and place back into the cell in main.xib.
However I still have the cells from main.xib that overlay (tvcells) that overlay my search.xib.
Also it seems that none of the code is initializing for search.xib, I put an NSlog message in viewdidload in the search.xib, and nothing shows up in the console, letting me know that none of that code was executed.
Any idea why?
Thanks!
CGRect container = [[UIScreen mainScreen]bounds];
container.origin.x = 0;
container.origin.y = 0;
NSArray *views = [[NSBundle mainBundle] loadNibNamed: #"ingredientSearchViewController" owner: self options: nil];
UIView *referencedView = (UIView *)[views objectAtIndex:0];
referencedView.frame = container;
[self.subView addSubview:referencedView];
NSLog(#"loaded subview but obviously not in subview xib");
Additional code that attempts to do this as a controller
if (self != nil){
[self.view removeFromSuperview];
}
if(self == nil){
ingredientSearchViewController *vc = [[[ingredientSearchViewController alloc]initWithNibName:#"ingredientSearchViewController" bundle:nil] autorelease];
vc.view.frame = [UIScreen mainScreen].applicationFrame;
vc.delegate = self;
[self.subView addSubview:vc.view];
}
viewDidLoad is a method in NSViewController.
And you are creating a View from Nib, therefore you should use the equivalent method awakeFromNib for NSView.
I'm trying to mimic the facebook ios side menu and have it working however the issue I am having is that I cannot send the sidemenu to the back as discussed in another question on SO iphone facebook side menu using objective c. I'm not using the library suggested but instead using the code that was suggested. I have
- (void)viewDidLoad
{
NSLog(#"View Did Load is running");
activitySpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activitySpinner.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
activitySpinner.center = self.view.center;
[self.view addSubview:activitySpinner];
SideMenuView *myDelegate = [[SideMenuView alloc] init];
[self setSideMenuDelegate:myDelegate];
//set the delegate's currentViewController property so that we can add a subview to this View.
[sideMenuDelegate setCurrentViewController:self];
//sideMenu = [[SideMenuView alloc] initWithNibName:#"SideMenuView" bundle:nil];
[self.view addSubview:myDelegate.view];
[self.view sendSubviewToBack:myDelegate.view];
[super viewDidLoad];
self.searchDisplayController.searchBar.scopeButtonTitles = nil;
[self fetchCustomers];
// Do any additional setup after loading the view, typically from a nib.
}
In my controller where I want the side menu but the view seems to get loaded into the current view instead of just going to the back so it can be seen when I slide the menu over.
Can someone help me get the myDelegate view to the back?
I am not entirely sure what you are trying to accomplish, so I have to guess. It sounds like you want to hide myDelegate.view behind self.view. It won't work this way.
sendSubviewToBack: sends the subview to the back of the view hierarchy of the sender, in your case, self.view. It will never send a subview below its superview.
You can instead add myDelegate.view as a subview to self.views superview, and put it behind self.view:
[[self.view superview] insertSubview:myDelegate.view belowSubview:self.view];
I've decided to just go with https://github.com/Inferis/ViewDeck and let that manage the views.
I have a UITableView in a UINavigationController that contains a rightBarButtonItem which should hide the UITableView and show an MKMapView instead. The button seems to work great: it hides the UITableView, and shows the MKMapView. However, this MKMapView is empty. As in, completely white. I've tried to use a UILabel (just for testing purposes), and that doesn't appear either, so the problem must occur when I add the MKMapView (and UILabel) to the view hierarchy. Some relevant code:
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView = [[MKMapView alloc] init];
mapView.hidden = YES;
[self.view addSubview:self.mapView];
// Some other stuff, table set up, etc.
}
That is the viewDidLoad of a class that inherits from UITableViewController. Now, I use the following method that gets called when tapped on the rightBarButtonItem of the UINavigationController:
- (void) toggleView {
if (self.mapView.isHidden) {
self.mapView.hidden = NO;
self.tableView.hidden = YES;
self.viewButton.title = #"List";
}
else {
self.mapView.hidden = YES;
self.tableView.hidden = NO;
self.viewButton.title = #"Map";
}
}
I am certain that function gets called, I have checked using NSLog. Also, the UITableView correctly disappears, and, I assume, the MKMapView (or whatever other UIView object for that matter) appears, but is empty/completely white. Does anybody see why I'm not seeing maps when trying to switch to Map View?
You should give it a size and position.
CGSize size = self.view.frame.size;
self.mapView =[[MKMapView alloc] initWithFrame:CGRectMake(0,0, size.width, size.height)];
To check the size in the console, add the following line in your toogleview method:
NSLog(#"%#", self.mapView);
Situation:
I'm trying to display a loading screen while waiting for my asynchronous connection to return with data to populate the tableview.
Problem:
Creating and adding the loadingscreen works fine, however, the tableview draws its lines over it, see screenshot:
.
Code: I add the view with these lines:
-(void) viewDidLoad{
[super viewDidLoad];
_loadScreen = [[LoadScreen alloc] initWithFrame:self.view.bounds];
[self.view addSubview: _loadScreen];
[self fetchRemoteData];
}
Question: Is it possible to add the loading view ontop of the table? Or can i make sure the tableview does not draw its lines untill i call reloadData?
-Thanks in advance,
W
I've done it like this many times:
-(void) viewDidLoad{
[super viewDidLoad];
_loadScreen = [[LoadScreen alloc] initWithFrame:self.view.bounds];
[self.tableView addSubview: _loadScreen];
self.tableView.hidden = YES;
[self fetchRemoteData];
}
- (void)dataFetchedSuccessfully
{
self.tableView.hidden = NO;
}
Just hide the tableview and show it again when the data has been loaded.
There is some approaches that will solve you problem:
-Set a footer view for the table view, so all lines should disappear.
self.tableView.tableFooterView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
-I assume that you use UItableViewController. If so self.view and self.tableView both represents the same view, so by setting:
self.tableView.hidden = NO;
It will hide even your loading view. What I encoure you to do is to create a custom view which has an table view as its subview. Then you can hide this table view by only showing an loading view.
Hope I could help.
I have a core data application which uses a navigation controller to drill down to a detail view and then if you edit one of the rows of data in the detail view you get taken to an Edit View for the that single line, like in Apples CoreDataBooks example (except CoreDataBooks only uses a UITextField on its own, not one which is a subview of UITableViewCell like mine)!
The edit view is a UITableviewController which creates its table with a single section single row and a UITextfield in the cell, programatically.
What I want to happen is when you select a row to edit and the edit view is pushed onto the nav stack and the edit view is animated moving across the screen, I want the textfield to be selected as firstResponder so that the keyboard is already showing as the view moves across the screen to take position. Like in the Contacts app or in the CoreDataBooks App.
I currently have the following code in my app which causes the view to load and then you see the keyboard appear (which isn't what I want, I want the keyboard to already be there)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[theTextField becomeFirstResponder];
}
You can't put this in -viewWillAppear as the textfield hasn't been created yet so theTextField is nil. In the CoreDataBooks App where they achieve what i want they load their view from a nib so they use the same code but in -viewWillAppear as the textfield has already been created!
Is there anyway of getting around this without creating a nib, I want to keep the implementation programatic to enable greater flexibility.
Many Thanks
After speaking with the Apple Dev Support Team, I have an answer!
What you need to do is to create an offscreen UITextField in -(void)loadView; and then set it as first responder then on the viewDidLoad method you can set the UITextField in the UITableViewCell to be first responder. Heres some example code (remember I'm doing this in a UITableViewController so I am creating the tableview as well!
- (void)loadView
{
[super loadView];
//Set the view up.
UIView *theView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.view = theView;
[theView release];
//Create an negatively sized or offscreen textfield
UITextField *hiddenField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, -10, -10)];
hiddenTextField = hiddenField;
[self.view addSubview:hiddenTextField];
[hiddenField release];
//Create the tableview
UITableView *theTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStyleGrouped];
theTableView.delegate = self;
theTableView.dataSource = self;
[self.view addSubview:theTableView];
[theTableView release];
//Set the hiddenTextField to become first responder
[hiddenTextField becomeFirstResponder];
//Background for a grouped tableview
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//Now the the UITableViewCells UITextField has loaded you can set that as first responder
[theTextField becomeFirstResponder];
}
I hope this helps anyone stuck in the same position as me!
If anyone else can see a better way to do this please say.
Try do it in viewDidAppear method, works for me.
I think the obvious solution is to create the textfield in the init method of the view controller. That is usually where you configure the view because a view controller does require a populated view property.
Then you can set the textfield as first responder in viewWillAppear and the keyboard should be visible as the view slides in.
have you tried using the uinavigationcontroller delegate methods?:
navigationController:willShowViewController:animated: