my problem might be simple to some of you but i can't find a solution. I have a method where a create my views automatically (text fields, labels and text views). It's like a registration form. The problem is that when i change the screen to landscape mode, i want to change the views width. To do that i used [self.view removeFromSuperview] and created the views again. The problem is that the views won't get recreated with the landscape width. I can't use IB to autosize the views at orientation change. The views are created in viewDidLoad and removed and recreated in - (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation {} I don't know why they don't get recreated after being removed. If there was another solution that you could share with me i would appreciate it.
Here's how i create the views:
-(void)createViews:(int)width
{
for(int i = 0; i < numberOfTextfields; i++) {
textfieldPadding = textfieldPadding+40;//set some space between the text fields
labelPadding = labelPadding+40;//set some space between the labels
UITextField *field = [[UITextField alloc] initWithFrame:
CGRectMake(10,i*textfieldHeight+textfieldPadding+firstTextfieldHeight+10,width, textfieldHeight)];
field.autoresizingMask = UIViewAutoresizingFlexibleWidth;
//field.backgroundColor= [UIColor cyanColor];
field.placeholder = [labels objectAtIndex:i];
field.borderStyle=UITextBorderStyleRoundedRect;
field.returnKeyType = UIReturnKeyDone;
[field addTarget:self action:#selector(doneButton:)
forControlEvents:UIControlEventEditingDidEndOnExit];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, i*labelHeight+firstLabelHeight+labelPadding-20, width, labelHeight)];
label.text = [labels objectAtIndex:i];
//label.backgroundColor = [UIColor brownColor];
[scrollView addSubview:field];
[scrollView addSubview:label];
[textfields addObject:field];
[labels addObject:label];
[field release];
[label release];
}
}
Here's where i wanted to remove them and recreate them:
- (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
[self.view removeFromSuperview];
[self createViews:landscapeWidth];
}
else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
[self.view removeFromSuperview];
[self createViews:portraitWidth];
}
}
Thanks in advance!
Instead of removing, resizing and then re-adding as you currently are why not just set the appropriate autoresizingMask (link) when you create the view initially?
UITextField *myTextField = [[UITextField alloc] initWithFrame:someRect];
// the following will automatically resize the width on orientation change
myTextField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[myView addSubview:myTextField];
[myTextField release];
Related
I am trying to create a custom look of my UINavigationBar. When the user puts the app in landscape, the navigationBar should be covered with an Image. When rotated back to portrait I want the View(Image) removed. Everything works fine with the code below except removing it. I can remove the View if I put the code in the same if-statement, but nothing happens if I put it in the else if-statement. Have I missed something ? / Regards
- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
UIView *v = [[UIView alloc]init];
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
v.frame = CGRectMake(0,0,480,44);
v.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"navbar25g.png"]];
[self.view addSubview:v];
//[v removeFromSuperview]; <----- works if I put it here
NSLog(#"LANDSCAPE");//load the landscape view
}
else if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
[v removeFromSuperview]; <----- Not working
NSLog(#"PORTRAIT"); //load the portrait view
}
}
the reason that you cannot remove it is every time you go into the method you create a new instance of the UIView *v.
Create an instance variable then assign the view to that. Once it is assigned you can then remove or add as needed.
If you do not want to use an instance variable then you can give the view a tag i.e.
UIView *v = nil;
v = [self.view viewForTag:1000];
if (!v) {
v = [[UIView alloc] init];
v.tag = 1000;
v.frame = CGRectMake(0, 0, 480, 44);
v.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"navbar25g.png"]];
}
Now you can do your adding and removing for it.
Have you tried UIAppearance?
[[UINavigationBar appearance] setBackgroundImage:nil barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:image barMetrics:UIBarMetricsLandscapePhone];
I am looking for an example that show just vertical scrolling in iPhone.
The Apple supplied Scrolling example allows swiping of images left to
right.
Example Link
Example Link
I want to have my images scroll top to bottom like Instagram
App.
I research about it and found lots of example, but they all show
horizontal scrolling.
Example
Example
Example
Does anyone know how to do this?
I appreciate if you send me a link to a tutorial.
Hi i solved your problem with apple code,
just change the function with
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(0,curXLoc);
view.frame = frame;
curXLoc += (kScrollObjHeight);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake(([scrollView1 bounds].size.width),kNumImages * kScrollObjHeight)];
}
or if you want sample then i will give you
For your purpose refer your link:
http://idevzilla.com/2010/09/16/uiscrollview-a-really-simple-tutorial/
There is a code like:
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
For horizontal scrolling you need to set the width of contentSize property to a higher value than the scroll view's frame width. Likewise for vertical scrolling you need to set the height of contentSize property to a higher value than the scroll view's frame height.
Reference
In the above code it can be done like:
scroll.contentSize = CGSizeMake(self.view.frame.size.width, numberOfViews * self.view.frame.size.height);
You can use the following code to scroll images from top to bottom and vice versa.!!
- (void)viewDidLoad
{
//....
UISwipeGestureRecognizer *recognizer;
//for scrolling up
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeUp)]; // calling method SwipeUp
[recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
[[self view] addGestureRecognizer:recognizer];
//for scrolling down
UISwipeGestureRecognizer *recognizer1;
recognizer1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeDown)]; //calling method SwipeDown
[recognizer1 setDirection:(UISwipeGestureRecognizerDirectionDown)];
[[self view] addGestureRecognizer:recognizer1];
}
//Initialise and synthesise IBOutlet UIImageView *bgImage;
-(IBAction)SwipeUp
{
[bgImage setImage:[UIImage imageNamed:#"yourImage1"] ];
bgImage.opaque=YES;
[self.view addSubview:bgImage];
}
-(IBAction)SwipeDown
{
[bgImage setImage:[UIImage imageNamed:#"yourImage2"] ];
bgImage.opaque=YES;
[self.view addSubview:bgImage];
}
I don't know if I understood correctly what you want to accomplish but basically you can set the position of you scrollView using setContentOffset.
CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
[scrollView setContentOffset:bottomOffset animated:YES];
There are several ways of doing this for example:
Using the UITableView with Custom cell
Adding UIScrollingView & adding the content/images & increasing the
height of scrollview according to number of objects in array.
Here is the code snippet which creates a 2*2 Grid for images :
//Over here adding the image names into the Array
NSMutableArray *imageArray=[[NSMutableArray alloc]init];
[Arr addObject:[UIImage imageNamed:#"image_1.png"]];
[Arr addObject:[UIImage imageNamed:#"image_2.png"]];
[Arr addObject:[UIImage imageNamed:#"image_3.png"]];
[Arr addObject:[UIImage imageNamed:#"image_4.png"]];
[Arr addObject:[UIImage imageNamed:#"image_5.png"]];
// Initlaizing the ScrollView & setting the frame :
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0,320, 460)];
[scrollView setBackgroundColor:[UIColor clearColor]];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
int row = 0;
int column = 0;
for(int i = 0; i < imageArray.count; i++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor=[UIColor clearColor];
button.frame = CGRectMake(column*160+0,row*210+10, 160, 190);
[button setImage:[imageArray objectAtIndex:i] forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor clearColor]];
[button addTarget:self action:#selector(chooseCustomImageTapped:) forControlEvents:UIControlEventTouchUpInside];
button.tag = i;
[view1 addSubview:button];
if (column == 1) {
column = 0;
row++;
} else {
column++;
}
}
[scrollView setContentSize:CGSizeMake(320, (row+1) * 210)];
[self.view addSubview:view1];
//Here is the method used for Tapping :
- (IBAction)chooseCustomImageTapped:(id)sender
{
}
Now,once the scrollView is ready for Vertical scrolling, you can do your own customization accordingly. I hope this would work for you.
I have a layout where i have two text fields one is for alphabetic input and another one for numeric input. I have set different type of keyboards for these like as default for alphabetic text field and number for numeric field.
I have added a done button on number pad. Still I am getting this a issue with keyboards that is when I taped on numeric text filed first then it show done button keyboard while I taped alphabetic text filed first and then taped on numeric text field then it doesn't add done button on number pad.
How do I solve it?
I have use these code to add button on number pad.
-(void)viewWillAppear:(BOOL)animated
{
// Register for the events
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector (keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
keyboardVisible = NO;
scroll_view.contentSize=CGSizeMake(320, 400);
}
- (void)keyboardDidShow:(NSNotification *)note {
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for (keyboard in tempWindow.subviews) {
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES)
if (numberPadShowing) {
[self addButtonToKeyboard];
return;
break;
} else {
for (UIView *v in [keyboard subviews]){
if ([v tag]==123)
[v removeFromSuperview];
}
}
}
}
-
(void) keyboardDidHide: (NSNotification *)notif
{
// Is the keyboard already shown
if (!keyboardVisible) {
return;
}
// Keyboard is no longer visible
keyboardVisible = NO;
}
-(void)doneButton
{
UIScrollView *scrollView =[[UIScrollView alloc] init];
scrollView=scroll_view;
[scrollView setContentOffset:svos animated:YES];
[myActiveTextField resignFirstResponder];
}
- (void)addButtonToKeyboard {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
[doneButton setImage:[UIImage imageNamed:#"DoneUp3.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:#"DoneDown3.png"] forState:UIControlStateHighlighted];
} else {
[doneButton setImage:[UIImage imageNamed:#"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:#"DoneDown.png"] forState:UIControlStateHighlighted];
}
[doneButton addTarget:self action:#selector(doneButton) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
[keyboard addSubview:doneButton];
} else {
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES)
[keyboard addSubview:doneButton];
}
}
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
myActiveTextField=textField;
if (myActiveTextField==txt_hour_section || myActiveTextField==txt_minute_section || myActiveTextField==txt_transport_time){
numberPadShowing=TRUE;
UIScrollView *scrollView =[[UIScrollView alloc] init];
scrollView=scroll_view;
svos = scrollView.contentOffset;
CGPoint pt;
CGRect rc = [textField bounds];
rc = [textField convertRect:rc toView:scrollView];
pt = rc.origin;
pt.x = 0;
pt.y -= 60;
[scrollView setContentOffset:pt animated:YES];
}
else{
numberPadShowing=FALSE;
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
UIScrollView *scrollView =[[UIScrollView alloc] init];
scrollView=scroll_view;
[scrollView setContentOffset:svos animated:YES];
[textField resignFirstResponder];
return YES;
}
Thanks in advances...
I think your problem is becuase you are tapping in to the numeric field after tapping the alpha field, and the alpha keyboard is already in view. Therefore when you tap the number field (whilst alpha keyboard still in view) it doesn't fire the 'keyboardDidShow' event, as the keyboard is already showing from the previous field (albeit a alpha one).
Try putting your done button logic into a delegate method for the textfield 'textFieldDidBeginEditing' event for the number field.
If my first answer doesn't work in your implementation, then you might want to consider a restructure and go for setting the inputAccessoryView of your UITextField. Code along these lines should do the trick (you can put this in your viewDidLoad nib, and also note that you'll need to implement the doneTapped method yourself);
// Create a UIToolbar object and set its style to be black and transparent
numericInputAccessoryView_ = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
numericInputAccessoryView_.barStyle = UIBarStyleBlackTranslucent;
// The flexible space item will push the done button to the far right
UIBarButtonItem *space = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
// Make the done button, this is a system item so you don't need to set the title or anything. This will call a method called "doneTapped:(id)sender" when you tap it, you'll need to implement that yourself.
UIBarButtonItem *done = [[UIBarButtonItem alloc]WithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneTapped:)];
// Stick the flexible space and the done button in your toolbar
numericInputAccessoryView_.items = [NSArray arrayWithObjects:space,done, nil];
// This would return it, if you had this in a separate method.
return numericInputAccessoryView_;
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
I created a custom UITableViewCell class with a UIButton, a UIImage, and two UILabels. The button and the image are overlayed on top of each other, and only one is displayed at a time. The expected behavior is you touch on the button, the button disappears, and it displays the image. The UITableViewCells are set to be reused. Here's my code:
Constructor:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
unheartButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
unheartButton.backgroundColor = [UIColor clearColor];
unheartButton.frame = CGRectMake(10, 13, 20, 18);
[unheartButton addTarget:self action:#selector(onButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[unheartButton setBackgroundImage:[UIImage imageNamed:#"redheart.png"] forState:UIControlStateNormal];
imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(12, 13, 16, 16);
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int ndx = 1; ndx < 13; ndx++) {
[array addObject:[UIImage imageNamed:[NSString stringWithFormat:#"icon-loading-%d (dragged).tiff", ndx]]];
}
imageView.animationImages = array;
imageView.animationDuration = 1;
[array release];
[self.contentView addSubview:imageView];
[self.contentView addSubview:unheartButton];
return self;
}
}
- (void) setModel:(MyModel *)myModel {
model = myModel;
if (model.hideImage) {
imageView.hidden = YES;
unheartButton.hidden = NO;
else {
imageView.hidden = NO;
unheartButton.hidden = YES;
}
}
Button click:
- (IBAction) onButtonClick: (id) sender {
model.hideImage = NO;
unheartButton.hidden = YES;
imageView.hidden = NO;
[imageView startAnimating];
[self setNeedsDisplay];
[self.contentView setNeedsDisplay];
[self.unheartButton setNeedsDisplay];
[self.imageView setNeedsDisplay];
}
I'm calling setNeedsDisplay on everything, but nothing seems to happen. If I scroll off the screen and back up, the button is hidden and now the loading icon is shown, but this only happens after a scroll. I'm not sure what I need to do to get the cell to repaint.
The UITableView does some fancy caching to support scrolling and the like; I've had similar issues with refreshing a specific cell when I use custom views.
You can use reloadRowsAtIndexPaths:withRowAnimation: to make the table reload just that row. See this post for more information: Why won't my UITableViewCell deselect and update its text?