I use the following code to hide searchbar:
- (void)updateContentOffset
{
self.tableView.contentOffset = CGPointMake(0, 44);
}
- (void)viewWillAppear:(BOOL)animated
{
NSLog(#"%s",__PRETTY_FUNCTION__);
[super viewWillAppear:animated];
[self searchBarShouldEndEditing:self.searchDisplayController.searchBar];
[self performSelector:#selector(updateContentOffset) withObject:nil afterDelay:0.0];
self.fetchedResultsController.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.fetchedResultsController performFetch:nil];
[self.tableView reloadData];
[self.tableView scrollRectToVisible:CGRectMake(0, 44, 1, 1) animated:YES];
}
The code works perfectly when view is shown for the first time.
Next time it's shown(returning from another controller) it slides a bit down than it should be and I have no idea why it happens.
OK, in my case I played with a delay and found that making it 0.1 makes it work as planned.
[self performSelector:#selector(updateContentOffset) withObject:nil afterDelay:0.1];
Related
I've been struggling with this now for a long time. Where is my mistake? At the moment the hide and show seems to work, but everytime I come "back" to my viewcontroller I see that my view is shifted up, but there is no ad in there. But the first time I see the view controller, there is an ad. What am I doing wrong?
I just want to show the same ad across view controllers and this is like the parent UIViewController class, a lot of other view controllers inherit from:
#pragma mark View lifecycle
-(void)viewDidLoad
{
[super viewDidLoad];
if(![[NSUserDefaults standardUserDefaults] objectForKey:kInAppPurchaseNoAds]){
self.bannerContainer = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).bannerView;
self.bannerContainer.frame = CGRectOffset(self.bannerContainer.frame, 0, self.view.frame.size.height);
[self.view addSubview:self.bannerContainer];
}
}
//Handle the in app purchases
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//iAd
if(![[NSUserDefaults standardUserDefaults] objectForKey:kInAppPurchaseNoAds] && !self.bannerContainer){
self.bannerContainer.delegate = self;
}
if(self.bannerContainer.bannerLoaded){
[self showBanner];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkIAdPurchase) name:IAPHelperProductPurchasedNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self hideBanner];
self.bannerContainer.delegate = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:IAPHelperProductPurchasedNotification object:nil];
}
#pragma mark Check iAd purchase
-(void)checkIAdPurchase
{
if([[NSUserDefaults standardUserDefaults] objectForKey:kInAppPurchaseNoAds] && self.bannerContainer){
[self hideBanner];
[self.bannerContainer removeFromSuperview];
self.bannerContainer.delegate = nil;
self.bannerContainer = nil;
}
}
#pragma mark IAd delegate
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
[self showBanner];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[self hideBanner];
}
#pragma mark Show and hide the banner
- (void)showBanner
{
if(!self.isBannerVisible){
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.5
animations:^{
//Restore the constraint
self.mainViewBottomConstraint.constant = 50;
//Move the banner on
self.bannerContainer.frame = CGRectOffset(self.bannerContainer.frame, 0, -50);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.isBannerVisible = YES;
}];
}
}
- (void)hideBanner
{
if(self.isBannerVisible){
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.5
animations:^{
//Restore the constraint
self.mainViewBottomConstraint.constant = 0;
//Move the banner off
self.bannerContainer.frame = CGRectOffset(self.bannerContainer.frame, 0, self.bannerContainer.frame.size.height);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.isBannerVisible = NO;
}];
}
}
Actually you are creating instance of iAd in AppDelegate and that's only one in the whole app.Now when you first time come to Vc then due to code in viewdidload it add to your Vc..
Now when you move to other view controller that viewcontroller also add iAd at viewdidload..You have only one object of iAd so it will add to at a time in One VC..So when you move to other Vc iAd will remove from that Vc and add to new VC..
Solution : You should call iAD subview code in ViewWillAppear...
I'm trying to understand how to minimize my transition time between my view controllers.
For some reason, segment switching to one of my controllers takes 1204.0 ms.
In instruments it is telling me that this method is taking 964.0 ms.
- (void)goToNextContentViewController
{
self.index = [NSNumber numberWithInt:1];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MusicPlayerQueue" bundle:nil];
SABaseContentViewController *queueViewController = [storyboard instantiateViewControllerWithIdentifier:#"Queue"];
queueViewController.rootViewController = self;
[self.pageViewController setViewControllers:#[queueViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:^(BOOL finished) {
}];
}
Specifically when I select a segmented control.
- (IBAction)segmentSwitch:(UISegmentedControl *)sender
{
UISegmentedControl *segmentedControl = (UISegmentedControl *) sender;
NSInteger selectedSegment = segmentedControl.selectedSegmentIndex;
if (selectedSegment == 0) {
[self goToPreviousContentViewController];
}
else{
[self goToNextContentViewController];
}
}
I am pushing to a tableViewController that is loading data that I am populating from a singleton. Any ideas why this is happening? My other segment tab loads the view controller at a much faster speed with the same method.
The strangest part is that the view loads pretty fast, ONLY when the tableView in the controller I am pushing to is populated with 3 or less objects from my SingletonArray. If the array is 3 or greater, it will load at a speed of 1000+ms....
Here is my viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView setEditing:YES];
self.editSelected = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:#"songEnded" object:nil];
}
I have a UISearchBar in iOS 6 app and it works perfectly, but in iOS 7 the cancel button and the clear button don't work and I can't return back. It's a big problem in my app and I need to solve it.
My code is:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
// -- iOS 7 Hack
if (!SYSTEM_VERSION_LESS_THAN(#"7.0")) {
controller.searchResultsTableView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64);
[controller.searchContentsController.view setNeedsLayout];
}
[self filterContentForSearchText:searchString scope:nil];
return YES;
}
- (void) searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
// iOS7 Hack
if (!SYSTEM_VERSION_LESS_THAN(#"7.0")) {
controller.searchResultsTableView.contentInset = UIEdgeInsetsMake(0.f, 0.f, 0.f, 0.f);
}
}
Thank you for advance.
Possbile duplicate: UISearchBar's Cancel and Clear Buttons Not Working in iOS 7
EDIT:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
self.searchDisplayController.searchBar.hidden = YES;
self.tempImageView.hidden = NO;
[searchBar resignFirstResponder];
}
SOLUTION:
With this function I resolved the problem:
-(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
controller.active = YES;
[self.view addSubview:controller.searchBar];
[self.view bringSubviewToFront:controller.searchBar];
}
Hope it helps!
IOS 7 default search bar will be transparent cancel button
- (void)searchBarCancelButtonClicked:(UISearchBar *)aSearchBar
{
[aSearchBar resignFirstResponder];
isSearching = NO;
aSearchBar.text = #"";
[diaryTableView reloadData];
}
With this function I resolved the problem:
-(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
controller.active = YES;
[self.view addSubview:controller.searchBar];
[self.view bringSubviewToFront:controller.searchBar];
}
Hope it helps!
I implemented a search bar and search display controller on top of my table view.
When the view loads the search bar and relative scopes are always visible.
Is there a simple way to hide it until the user scrolls down, like it happens in the Music app?
You need to add search bar as a header of the table view and then set the contentoffset property of table view in viewDidLoad as,
[self.tableView setContentOffset:CGPointMake(0,44) animated:YES];//or (0, 88) depends on the height of it
For search display controller, you can try this as well,
[self.searchDisplayController setActive:NO animated:YES];
another approach without hardcode
[self.tableView setContentOffset:CGPointMake(0.0, self.tableView.tableHeaderView.frame.size.height) animated:YES];
After a few hours of hair pulling, something that works
on iOS 9
doesn't depend on the number of rows in the table
with variable height rows
Considering the searchbar is the tableView.tableHeaderView
#interface MyTableViewController ()
#property (nonatomic, assign) BOOL firstLayout;
#end
- (void) viewDidLoad {
[super viewDidLoad];
self.firstLayout = YES;
//your code
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
if(self.firstLayout){
CGPoint offset = CGPointMake(0, self.tableView.tableHeaderView.frame.size.height - self.tableView.contentInset.top);
[self.tableView setContentOffset:offset];
self.firstLayout = NO;
}
}
for iOS 7 and using UINavigationController
[self.tableView setContentOffset:CGPointMake(0, self.searchBar.height + self.navigationController.navigationBar.height)];
Best way i did reload tableview in
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self performSelector:#selector(reload:) withObject:nil afterDelay:0.0];
self.edgesForExtendedLayout = UIRectEdgeNone;
}
- (void)reload:(__unused id)sender {
[self.searchDisplayController setActive:YES];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
} else {
[self.refreshControl endRefreshing];
[[[UIAlertView alloc]initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
}
Thanks
This works fine on iOS9+
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableView.contentOffset = CGPointMake(0, -20);
});
}
I am trying to use dismissModalViewController:Animated: to dismiss my view, but it is not dismissing it, no matter what I try. You can see my attempts to release the view in the hideSplash method at the bottom. Please, if anyone can help it would be greatly appreciated. My code posted below:
#import "SplashViewController.h"
#implementation SplashViewController
- (void) didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload {
}
- (void) dealloc {
[super dealloc];
}
-(void) showSplash {
modalViewController = [[UIViewController alloc] init];
modalViewController.view = modelView;
[self presentModalViewController:modalViewController animated:NO];
[activityIndicator startAnimating ];
//[self bigcalculation];
//[self performSelector:#selector(hideSplash) withObject:nil afterDelay:2.0];
}
- (void) viewDidAppear:(BOOL)animated {
NSLog(#"View Did Appear");
[self bigcalculation];
}
- (void) bigcalculation {
NSLog(#"Big Calc Start");
for (int i = 0; i <= 648230; i++) {
for (int j = 0; j <= 1200; j++) {
}
}
NSLog(#"Big Calc End");
[self performSelector:#selector(hideSplash) withObject:nil];
}
- (void) hideSplash {
NSLog(#"Hide");
//[self dismissModalViewControllerAnimated:NO];
//[[self parentViewController] dismissModalViewControllerAnimated:YES];
[[self modalViewController] dismissModalViewControllerAnimated:YES];
NSLog(#"End Hide");
}
#end
The modal view controller is not responsible for dismissal. That burden is placed on the view controller that called the modalViewController.
Try replacing:
[[self modalviewController] dismissModalViewControllerAnimated:YES];
with
[self dismissModalViewControllerAnimated:YES];
Try to use this:
[self.parentViewController dismissModalViewControllerAnimated:NO];
I found the solution in case anyone else has this issue the line
[self performSelector:#selector(hideSplash) withObject:nil];
Should be
[self performSelector:#selector(hideSplash) withObject:nil afterDelay:0.0];