I have a segmented controll with two cells defined programmatically. When I go into my app both cells perform the same action. The first should open a webpage in Safari, the second opens an image and covers the current view for 5 seconds. Any pointers?
In the .m file
#property UISegmentedControl *segment;
- (void)viewDidLoad
{
UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
self.tableView.tableHeaderView = segment;
[segment addTarget:self action:#selector(segmentPressed:) forControlEvents:UIControlEventValueChanged];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"UITableViewCell"];
}
- (void)segmentPressed:(id)sender {
if (_segment.selectedSegmentIndex ==0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"******"]];
}else if(_segment.selectedSegmentIndex ==1){
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
imageView.backgroundColor = [UIColor redColor];
[imageView setImage: [UIImage imageNamed:#"MACSLoad#2x.png"]];
[self.view addSubview: imageView];
sleep(5);
imageView.hidden = YES;
}
}
You get that result because _segment is nil. You never assigned the segmented control you created to your property -- you assigned it to a local variable. So change this line,
UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
to,
self.segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
Another way to do it, would be to get rid of the property all together, leave the code in viewDidLoad as it is, and change this,
- (void)segmentPressed:(id)sender {
if (_segment.selectedSegmentIndex ==0) {
to this,
- (void)segmentPressed:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex ==0) {
Unless you need to access the segmented control outside of its action method, there's no reason to create the property. It's better in any case to use the sender argument rather than a property (even if you have one) inside the action method.
Related
I have declared 4 images in the ViewDidLoad in my ViewController and then hide them with myImage1.hidden = YES;.
I was wondering if there was anyway of sending a message from the App Delegate (from within a Switch Case) to the ViewController's ViewDidLoad method, which sets the UIImageView to hidden: myImage1.hidden = NO;
-(void)playIndex:(NSInteger)index
{
switch (index)
{
case 1:
[self playOne];
[// something here to tell the UIImageView .hidden = NO;]
break;
I'm not sure this is possible but thought someone might be able to shed some light on what I'm trying to do. I really just want the image to become visible at the same time as the case 1: [self playOne]; when it's called.
If not done this way, is there another other method I could try to achieve this?
`- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
AppDelegate* app = [[UIApplication sharedApplication] delegate];
UIImage *redSquare = [UIImage imageNamed:#"red_square.png"];
UIImage *blueSquare = [UIImage imageNamed:#"blue_square.png"];
UIImage *greenSquare = [UIImage imageNamed:#"green_square.png"];
UIImage *yellowSquare = [UIImage imageNamed:#"yellow_square.png"];
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(72, 117, 60, 60)];
UIImageView *imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(188, 117, 60, 60)];
UIImageView *imageView3 = [[UIImageView alloc] initWithFrame:CGRectMake(72, 254, 60, 60)];
UIImageView *imageView4 = [[UIImageView alloc] initWithFrame:CGRectMake(188, 254, 60, 60)];
[self.view addSubview:imageView1];
[self.view addSubview:imageView2];
[self.view addSubview:imageView3];
[self.view addSubview:imageView4];
imageView1.animationImages = #[redSquare];
imageView2.animationImages = #[blueSquare];
imageView3.animationImages = #[greenSquare];
imageView4.animationImages = #[yellowSquare];
imageView1.animationDuration = 1;
imageView2.animationDuration = 1;
imageView3.animationDuration = 1;
imageView4.animationDuration = 1;
imageView1.hidden = YES;
imageView2.hidden = YES;
imageView3.hidden = YES;
imageView4.hidden = YES;
[imageView1 startAnimating];
[imageView2 startAnimating];
[imageView3 startAnimating];
[imageView4 startAnimating];
The Switch statement in the app delegate is: (Including the ViewController reference)
-(void)playIndex:(NSInteger)index
{
ViewController* mainController = (ViewController*) self.window.rootViewController;
switch (index)
{
case 1: [self playOne]; [mainController imageView1Hidden]; break;
case 2: [self playTwo]; break;
case 3: [self playThree]; break;
case 4: [self playFour]; break;
}
}
You can do this by :
Property variable of that ViewController.
By firing local Notification
It's definitely possible, although you probably shouldn't include this logic in the app delegate (but I admit I'd need more context to direct you otherwise).
You can access your view controller from the app delegate. See the answer to this question on how to do that:
How do I access my viewController from my appDelegate? iOS
Then, in your view controller you could have properties (of type BOOL) that specify whether the corresponding image views should be visible. Something like this in your view controller's .h file:
#property BOOL imageView1Hidden;
Then, in your switch statement you would set that property, and in the viewDidLoad method (of your view controller) you could check those properties to determine whether to set the hidden state for the image views.
Not entirely elegant, but it would work.
My app looks like this when you launch it:
On every row except for the top one, I can push a new view controller, and dismiss it, and everything stays the same. However, if I click the Instagram row, and then dismiss the view that is pushed onto it, my screen looks like this:
In the Instagram controller that is pushed, the viewDidLoad looks like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Instagram";
UIBarButtonItem *theButton = [[UIBarButtonItem alloc] initWithTitle:#"Post" style:UIBarButtonItemStylePlain target:self action:#selector(doit)];
self.navigationItem.rightBarButtonItem = theButton;
self.downloading = YES;
self.mediaArray = [NSMutableArray arrayWithCapacity:0];
[self.collectionView registerClass:[SBInstagramCell class] forCellWithReuseIdentifier:#"SBInstagramCell"];
[self.collectionView setBackgroundColor:[UIColor whiteColor]];
[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:#"footer"];
[self.navigationController.navigationBar setTranslucent:NO];
[self.view setBackgroundColor:[UIColor whiteColor]];
self.multipleLastEntities = [NSArray array];
self.instagramController = [SBInstagramController instagramControllerWithMainViewController:self];
self.instagramController.isSearchByTag = self.isSearchByTag;
self.instagramController.searchTag = self.searchTag;
[self downloadNext];
self.collectionView.alwaysBounceVertical = YES;
refreshControl_ = [[SBInstagramRefreshControl alloc] initInScrollView:self.collectionView];
[refreshControl_ addTarget:self action:#selector(refreshCollection:) forControlEvents:UIControlEventValueChanged];
loaded_ = YES;
[self showSwitch];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
}
I get to this view like this:
SBInstagramController *instagram = [SBInstagramController instagram];
instagram.showOnePicturePerRow = YES; //to change way to show the feed, one picture per row(default = NO)
instagram.showSwitchModeView = YES; //show a segment controller with view option
[instagram refreshCollection]; //refresh instagram feed
[self.navigationController pushViewController:instagram.feed animated:YES];
To me, it looks like the UIImageView is being shifted down about 44 pixels, which would be the space of a Navigation Bar, I just can't understand why it would be doing that. I use AutoLayout and have both the UITableView and the UIImageView pinned to the top superview, but it is only the UIImageView that moves.
I have custom UIBarButton items added to UINavigationBar as rightbarbuttonitems. I add two more items in UIBarButton when device goes to landscape mode. I am getting rotation call and I am correctly removing items from UIBarbuttons array based on device orientation, but my navigationbar item set never gets updates.
If i start with portrait mode, it shows what it suppose to. When I rotate to landscape new items are not added to navigation bar and vice versa extra item won't go when device go to portrait.
I am not sure how I can change navigationbaritems on device rotation. Per me I am doing all things correct.
-(void)setUpOnRotation:(BOOL)toPortrait{
_searchMessage = [[UILabel alloc] initWithFrame:CGRectMake(3.0, 0, 110, 20)];
_searchMessage.numberOfLines = 2;
_searchMessage.textColor = [UIColor blackColor];
_searchMessage.font = [UIFont systemFontOfSize:8.0];
_searchMessage.text = #"";
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 15, 130, 25)];
_searchBar.delegate = self;
_searchBar.showsCancelButton = NO;
UIBarButtonItem* doneButton = [BarButtons doneButtonWithTarget:self action:#selector(cancel)];
UIBarButtonItem *searchActivityItem = [[UIBarButtonItem alloc] initWithCustomView:_searchMessage];
UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithCustomView:_searchBar];
UIBarButtonItem *in = [BarButtons nativeButtonNamed:#"In"
title:#"In"
target:self
action:#selector(In)];
UIBarButtonItem *out = [BarButtons nativeButtonNamed:#"Out"
title:#"Out"
target:self
action:#selector(Out)];
NSMutableArray *itemsSet;
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
searchItem,
searchActivityItem,
doneButton, nil];
if (toPortrait) {
if ([itemsSet containsObject:searchItem] || [itemsSet containsObject:searchActivityItem]) {
[itemsSet removeObject:searchActivityItem];
[itemsSet removeObject:searchItem];
}
}
[_searchBar release];
[searchItem release];
[_searchActivity release];
[_searchMessage release];
[searchActivityView release];
self.navigationItem.rightBarButtonItems = itemsSet;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self setUpOnRotation:UIInterfaceOrientationIsPortrait(toInterfaceOrientation)];
} -(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
[self setUpOnRotation:UIInterfaceOrientationIsPortrait(self.interfaceOrientation)];}
Note: setUpOnRotaion method is called from willAnimateRotationToInterfaceOrientation and viewWillAppear with UIInterfaceOrientationIsPortrait(self.intefaceOrientation) and it does give me correct result. I have debugged.
In willAnimateRotationToInterfaceOrientation change cehck for orientation
if([uidevice orientaiton]statusbarorientation]){
self.naviogationite.rightbarbuttonitems = #[btn1,btn2,btn3];
}
else{
self.naviogationite.rightbarbuttonitems = #[abtn1,abtn2,abnt3];
}
u can do like this
can u do like this
NSMutableArray *itemsSet;
if(!toPortrait){
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
searchItem,
searchActivityItem,
doneButton, nil];
}
if (toPortrait) {
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
doneButton, nil];
}
I have a UIViewController class that contains a UITableView. In the table view header, I have a UIToolbar containing, among other things, a UISearchBar. In iOS8, when I tap on the search bar to search, the search display controller animates the bar to the top of the screen as expected, but the search bar has no margin on the left hand side.
The most stripped down of the code that reproduces is as follows:
- (void)viewDidLoad {
[super viewDidLoad];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, [self tableView].frame.size.width, 44.0)];
if ([toolbar respondsToSelector:#selector(setBarTintColor:)]) {
[toolbar setBarTintColor:[UIColor lightGrayColor]];
}
[[self tableView] setTableHeaderView:toolbar];
UIView *searchBarView = [[UIView alloc] initWithFrame:[[[self searchDisplayController] searchBar] frame]];
[[[self searchDisplayController] searchBar] setBackgroundImage:[[UIImage alloc] init]];
[searchBarView addSubview:[[self searchDisplayController] searchBar]];
[[[self searchDisplayController] searchBar] setText:#""];
UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBarView];
[toolbar setItems:#[searchBarItem]];
}
Any help / suggestions is greatly appreciated.
Edit: This works correctly on iOS 6.1 and 7.0/1
It seem to be a iOS8 bug.
You can use a temporary solution from this
Basically, you can create a subclass of UIToolbar.
Then in subclass you just created, add this code to append missing space:
#define DEFAULT_APPLE_PADDING 20.0f
-(void)layoutSubviews{
[super layoutSubviews];
[self.subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
if ([NSStringFromClass(view.class) hasPrefix:#"UIToolbar"] &&
[NSStringFromClass(view.class) hasSuffix:#"Button"]) {
CGRect buttonFrame = view.frame;
if (buttonFrame.origin.x == 0) {
buttonFrame.origin.x = DEFAULT_APPLE_PADDING;
} else if (buttonFrame.origin.x + buttonFrame.size.width == self.bounds.size.width) {
buttonFrame.origin.x -= DEFAULT_APPLE_PADDING;
}
view.frame = buttonFrame;
}
}];
}
I have many view controller when i click on tableView cell it move to new view controller problem is that it takes alot of time to move to the next view may be due to view which is to load fetches data from server here is my code for the view which loads
- (void)viewDidLoad {
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
UIImageView *bottomImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Nav.png"]];
[bottomImageView setFrame:CGRectMake(0,690,1024,34)];
[self.view addSubview:bottomImageView];
UIButton *button1=[UIButton buttonWithType:UIButtonTypeCustom];
[button1 setFrame:CGRectMake(10.0, 2.0, 88, 40.0)];
[button1 addTarget:self action:#selector(loginPressed) forControlEvents:UIControlEventTouchUpInside];
[button1 setImage:[UIImage imageNamed:#"logoutN.png"] forState:UIControlStateNormal];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithCustomView:button1];
self.navigationItem.rightBarButtonItem = button;
self.title=#"Catalog";
popImageView.hidden=YES;
passwordLabel.hidden=YES;
userLabel.hidden=YES;
userNameTextField.hidden=YES;
userPasswordTextField.hidden=YES;
signInButton.hidden=YES;
tableView.hidden=NO;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
if(!categoryArray){
categoryArray =[[NSMutableArray alloc] init];
}
if(!userArray){
userArray =[[NSMutableArray alloc] init];
}
if(!subCategoryArray){
subCategoryArray =[[NSMutableArray alloc] init];
}
if(!subCategoryArrayOne){
subCategoryArrayOne =[[NSMutableArray alloc] init];
}
if(!subCategoryArrayTwo){
subCategoryArrayTwo =[[NSMutableArray alloc] init];
}
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
int count=[appDelegate.coffeeArray count];
NSLog(#"Arrays Content Are %d",count);
tableView.backgroundView = nil;
[super viewDidLoad];
}
is there any way so that view loads fast
Your view is not loading fast because of I guess those data set operation in viewDidLoad method . I think those are :
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
The one thing you could do is to move this operations to perform on the background thread . For that move this operations to the separate function and call that to perform on background from the view did load method :
-(void)dataOperations
{
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
}
and in viewDidLoad call this function in background:
[self performSelectorInBackground:#selector(dataOperations) withObject:nil];
Or you can directly call those method from viewDidLoad like :
[self performSelectorInBackground:#selector(setUpData) withObject:nil];