I'm trying to find why my spinner is not visible.
I have a custom UIActivityIndicatorView. I want to put it on the top of my custom UITableViewCell.
Here is my code:
[downloadingSpinner startSpinner];
Where startSpinner is
- (void) startSpinner{
[self setHidden:NO];
[spinner startAnimating];
}
When I call this startSpinner method, I can't see my spinner. I directly tried to solve my problem with this code:
[self.cellView bringSubviewToFront:downloadingSpinner];
Where cellView is the main view of my cell.
I also tried this code:
downloadingSpinner.layer.zPosition = 1000;
I finally checked the subviews of my main view (cellView). I can see 14 views and le 13th is my custom spinner.
I tried to change the order on the storyboard like this:
I don't have any other idea to put this spinner on top.
I simply add
[self.cellView bringSubviewToFront:downloadingSpinner];
just after I've added my custom UIScrollView. Thank you for your help and I hope this will help someone else.
Related
I have a view controller which I created with IB, It has a CollectionView that will load some data, during loading process I want to show an activity indicator. For that I set the center property on activityIndicator to be equal to the center property of collectionView.
the problem is that I don't know on which method of viewController should I do this. I tried it first inside viewDidLoad method but inside this method the frame of collectionView is equal to what it was inside IB and activityIndicator can't be set properly.
So my questions are :
I want to know where should I do this kind of positioning of UIView objects
When does ios sdk give the views the sizes they should have in respect of the device the app is running on not the IB.
What happens inside of viewController methods like viewDidLoad and viewWillLayoutSubviews when we call those methods on super object of viewController like [super viewDidLoad]
All drawing-related operations should be performed on your application’s main thread then you could create it in the viewDidLoad or any other delegate function.
Threading Considerations
Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.
dispatch_async(dispatch_get_main_queue(),{
// Call function here.
})
For Reference [UIView] :
(https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html)
1. I want to know where should I do this kind of positioning of UIView objects
If you're using interface builder, you should be positioning them in interface builder using autolayout, otherwise pretty much anywhere on the main thread is fine. Sometimes you may need to call [self.view setNeedsLayout] / [self.view setNeedsDisplay] depending on what time of change you've made, but ultimately for normal CGRectMake calls you're fine.
2. When does ios sdk give the views the sizes they should have in respect of the device the app is running on not the IB.
UIView has a method called layoutSubviews
Otherwise for VC look at viewWillLayoutSubviews and viewDidLayoutSubviews called either side of that
3. What happens inside of viewController methods like viewDidLoad and viewWillLayoutSubviews when we call those methods on super object of viewController like [super viewDidLoad]
In general for these methods you should call super at the top of the override to get whatever is happening underneath out of the way. Then proceed to work...
-(void)viewDidLoad
{
[super viewDidLoad];
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, self.view.bounds.size.width, 100.0f)];
myView.backgroundColor = [UIColor redColor];
myView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:myView];
}
The above will work completely fine. No need for viewDidAppear. Look into auto layout and auto resizing. Personally I think working in code and not interface builder is better... but that's a personal choice.
You shoud use MBProgressHud the great library to show activity indicator. Just downlod this from github. drag and drop MBProgressHud.h and MBProgressHud.m in your project. Import .h file in your class.
then call , [MBProgressHUD showHUDAddedTo:self.view animated:YES];
and call when want to dissmiss or hide,
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do something...
//using main thread to hide immediately
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
});
It will automatically maintain center and other kind of stuff. That's it. Hope this will help. :)
I have MKMapView on which and I want to display UIView dynamically over the MapView but view never comes to the front. So, what is the solution to this problem?
Try to call the below method. Where you are want show UIView.
yourViewObject.layer.zPosition = 1
Try to call the below method when you wants to bring the view to the front.
[self.view bringSubviewToFront:yourView];
Else
Create a view above the MkMapView and Dynamically Show/hide the view using the following:
[yourView setHidden:NO];
Simply use:
[self.view bringSubviewToFront:yourView];
or
If you are adding your view in mapView,
[mapView bringSubviewToFront:yourView];
If it does not work then please post some of your code.
I have done markup code for different images. When the image changes, the markup and button still remain on screen. only it changes when i make a new markup on it.
The below image shows the button and markup of beach image.
Please help me...
You might be using viewController.view instead of inhering UIView.
So now you can call a viewcontroller's instance method on didSelectRowAtIndexPath event, which will clear all the widgets from the existing view.
- (void)clearSubviewsFromContainerView
{
for(UIView *view in [containerView subviews])
{
[view removeFromSuperview];
}
[self createNewWidgets];
}
Then call another method to generate and load new widgets.
- (void)createNewWidgets
{
// add new buttons, images over here in the same container view
}
Hope this might help you out.
I'd like to place an ADBannerView object onto my UITableView screen statically, what means that I want it to always stay above my toolbar (self.navigationController.toolbar), even when the user is scrolling the tableview. I've solved this by adding by ADBannerView as a subview to my toolbar and given it negative values for the frames origin:
[self setBannerViewSize];
[self.navigationController.toolbar addSubview:bannerView];
The only problem is: I can't click and open the iAd this way - I can see the banner but nothing happens when I tap on it.
Since I'm also using a refreshControl, the option to use a UIViewController instead of UITableViewController and add a tableView manually wouldn't work for me. Is there any other way I can get my ADBannerView statically showing in my table view controller AND still being tappable?
Thank you in advice!
Yay!! After all I succeeded in solving this (really annoying) problem by myself (and a lot of reading around)!
First, I found this really world-changing post. Basically this post handles with the topic that a UITableViewController uses self.view for its tableView property, so overriding the tableView property (or synthesizing it manually) plus giving self.view a new view (from application) and adding tableView as its subview would make it possible to reach the real superview of tableView.
But this still didn't solve my problem, although I was sure it would, because it all made sense. My bannerView appeared in the right place (and was fixed) but it still didn't do anything when clicked. But there was a second minor thing I didn't know about:
As I read in this post the superview of a subview doesn't only have to be userInteractionEnabled but also have a non-transparent backgroundColor. Because my superviews background color was set to [UIColor clearColor] it all didn't work - but setting its backGroundColor to e.g. blackColor solved the whole problem: the bannerView got finally tappable! :)
So, my code is now looking like this:
#synthesize tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
if (!tableView && [self.view isKindOfClass:[UITableView class]]) {
tableView = (UITableView *)self.view;
}
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.tableView.frame = self.view.bounds;
[self.view addSubview:self.tableView];
[self resizeTableToFitBanner];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:bannerView];
// some other code
}
BannerViewController in Apple's iAdSuite sample code solves this problem very elegantly:
https://developer.apple.com/library/ios/samplecode/iAdSuite/Introduction/Intro.html
I think you should use a container view, and set things up in IB. You can add a tool bar and ADBannerView to the bottom of the view of your navigation controller's root view controller. Fill the rest of the space with a container view - this will give you an embedded view controller automatically. You should delete this one and then drag in a tableViewController and control drag from the container view to the tableViewController to hook up the embed segue.
I have this bug that I'm struggling with for a few days now. I basically want to make a profile much like Instagram has.
When you click on one of the first two buttons in the upper "tab bar" the content is displayed in the lower part. The upper part of the screen stays the same. I have some UIViewControllers and some UITableViewController. I have like 5 buttons that are suppose to display the viewcontrollers. My problem is that I can display a tableviewcontroller but if I try to display the second and then go back to the first, for instance, it gets stuck to the last one I displayed. I hope this is clear enough. here is the code for displaying the viewcontroller.
- (IBAction)wallButtonPressed:(id)sender
{
if(!_userWallViewController) {
self.userWallViewController = [[WallViewController alloc] init];
self.userWallViewController.activityFeedTableView.bounds = self.containerView.bounds;
}
[self.currentViewController.view removeFromSuperview];
[self.currentViewController removeFromParentViewController];
self.currentViewController = self.userWallViewController;
self.userWallViewController.searchURLString = [NSString stringWithFormat:#"/event/user/%#", self.userID];
self.userWallViewController.containerView = self.containerView;
[self.containerView addSubview:self.userWallViewController.view];
[self addChildViewController:self.userWallViewController];
[self.userWallViewController.view setNeedsDisplay];
[self.userWallViewController viewWillAppear:YES];
}
containerView is an UIView that takes the whole lower part of the screen. currentViewController is a placeholder viewController and userWallViewController is a UITableViewController.
Any kind of help is much appreciate. This is a real bugging situation. Thanks
I was doing a stupid mistake that was hard to identify bu #Matt's suggestion helped.
[self.fanOfViewController.containerView addSubview:self.fanOfViewController.userSimpleTableView];
[self.currentViewController.view removeFromSuperview];
[self.currentViewController removeFromParentViewController];
self.fanOfViewController.containerView = self.containerView;
[self addChildViewController:self.fanOfViewController];
[self.containerView addSubview:self.fanOfViewController.view];
//CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS
[self.userWallViewController.activityFeedTableView removeFromSuperview];
[self.userFansViewController.userSimpleTableView removeFromSuperview];
Each time I was adding a new tableView from it's view controller by pressing the corresponding button I was stacking it in the current's view container. When I was trying to remove the corresponding viewController from the hierarchy and then add it again the viewDidLoad method was not called (it was only called the first time). The was where I had my logic of removing the tableView.
Now I'm also adding it when the button is pressed and remove the other tableViews from the "stack". It may not be the very best way but I do plan to optimize it. I hope this is clear enough and helps anybody that comes across this problem.