Setting frame on subview disables interaction - iphone

I have a UICollectionView with a long press Gesture recogniser for different cells.
I have a subview with two buttons on it.
The subview can be interacted with if my code is this
- (IBAction)longPress:(UILongPressGestureRecognizer *)sender {
if (sender.state != UIGestureRecognizerStateBegan) {
return;
}
NSArray * views = [[NSBundle mainBundle] loadNibNamed:#"RoomEditIconOverlay" owner:self options:nil];
UIViewController * editViewController = [views objectAtIndex:0];
[self.view addSubview:editViewController.view];
[editViewController.view becomeFirstResponder];//Required
}
However if i set the frame at any point then i just interact with the parental view.
- (IBAction)longPress:(UILongPressGestureRecognizer *)sender {
if (sender.state != UIGestureRecognizerStateBegan) {
return;
}
NSArray * views = [[NSBundle mainBundle] loadNibNamed:#"RoomEditIconOverlay" owner:self options:nil];
UIViewController * editViewController = [views objectAtIndex:0];
[editViewController.view setFrame:CGRectMake(0, self.view.frame.size.height -500, self.view.frame.size.width ,168)];
[self.view addSubview:editViewController.view];
[editViewController.view becomeFirstResponder];
}
I can have it at the wrong position (with no animations either) and be able to interact. Or have it in the correct position with no interaction.

The problem was caused by me setting the frame with not enough height.

Related

custom View for universal application

I believe, that this question is duplicated, but i can't find it =(.
How to create own UIView class, which is loaded from (iPhone/iPad)*.xib
I was trying next things:
#interface CurtainView : UIView
...
- (id)init {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self = [[[NSBundle mainBundle] loadNibNamed:#"CurtainView_iphone" owner:self options:nil] objectAtIndex:0];
[self setFrame:CGRectMake(0, 0, 320, 460)];
}
else {
self = [[[NSBundle mainBundle] loadNibNamed:#"CurtainView_ipad" owner:self options:nil] objectAtIndex:0];
[self setFrame:CGRectMake(0, 0, 768, 1004)];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
NSLog(#"there should be some animation on view appirance");
}
and ...
CurtainView* curtain = [[CurtainView alloc] init];
NSLog(#"before");
[self.view addSubview:curtain];
[curtain drawRect:CGRectMake(0, 0, 320, 460)];
But in this case, I haven't the result which I'm expecting, and drawRect isn't calling. I hope there is easy way to create custom Views for universal Apps.
put this code in .h file
#import
#interface CurtainView : UIView
#end
put this code in .m file
#import "CurtainView.h"
#implementation CurtainView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect{
// Drawing code
NSLog(#"there should be some animation on view appirance");
}
now call this UIView form your viewcontroller class. this will call drawRect
CurtainView* curtain = [[CurtainView alloc] init];
NSLog(#"before");
[curtain drawRect:self.view.frame];
[self.view addSubview:curtain];
you can call your viewcontroller class
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
} else {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
ok. sorry, I got my misstake:
it's need to use :
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:#"Curtain_iPhone" owner:self options:nil] objectAtIndex:0]];
instead my:
self = [[[NSBundle mainBundle] loadNibNamed:#"CurtainView_iphone" owner:self options:nil] objectAtIndex:0];
Hope it will helpful for some one.
moreover, I don't know why, but property "opaque" for the View should be set in "init" method, not only in IB.

Get UIWebView to scroll and bounce horizontally but not vertically

I have an iphone UIWebView with contents that are approx 1000px x 200px. Currently when scrolling with your finger, it'll bounce vertically but not horizontally.
I want it to do the opposite: bounce horizontally but not vertically.
Is there some trickery i need to do in my html to achieve this? Eg setting the width and height on the body explicitly maybe? Or is it a setting of the UIWebView? I can do the following to totally disable bouncing, is there something similar to set bouncing on a per-direction basis?
[[[webView subviews] lastObject] setBounces:NO];
Thanks a lot for the help
In iOS 5, you don't need to access the subviews. UIWebView contains a scrollView property to the nested UIScrollView:
To disable bounce:
webView.scrollView.bounces = NO;
To only bounce vertically:
webView.scrollView.alwaysBounceVertical = NO;
webView.scrollView.alwaysBounceHorizontal = YES;
You can try to add a CSS StyleSheet and set the a container Div with the dimension of your view. and apply the styleSheet to your UIWebView.
You can do it like that -
NSString *cssPath = [[NSBundle mainBundle] pathForResource:#"style" ofType:#"css"];
//do base url for css
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString *html =[NSString stringWithFormat:#"<!DOCTYPE html><html><head><link rel=\"stylesheet\" href=\"%#\" type=\"text/css\" /></head><body><section></section><br><br></body></html>",,cssPath];
[webView loadHTMLString:html baseURL:baseURL];
You can cycle through all the UIWebViews subviews(using a for loop) checking each one to see if it's a UIscrollView (using isMemberOfClass:) and then change the properties in the UIScrollView to meet your needs.
for (UIView *subview in [myWebView subviews]) {
if ([subview isMemberOfClass:[UIScrollView class]]) {
[(UIScrollView *)subview setAlwaysBounceVertical:NO];
[(UIScrollView *)subview setAlwaysBounceHorizontal:YES];
}
}
You can always do:
for (UIView *subview in [self.webView subviews]) {
SEL sel = #selector(setAlwaysBounceHorizontal:);
if( [subview respondsToSelector:sel] ){
[subview performSelector:sel withObject:(id)YES];
}
}
in your viewDidLoad

uipagecontrol indicator(dot)issue

Hai All...
I want to change the uipagecontroller indicator(dot) color...For that i'm doing the below steps.
Create new class named as PageControl with 2 methods
1.- (void) setCurrentPage:(NSInteger)page
2.- (void) setNumberOfPages:(NSInteger)pages
- (void) setCurrentPage:(NSInteger)page
{
NSLog(#"setCurrentPage");
[super setCurrentPage:page];
NSString* imgActive = [[NSBundle mainBundle] pathForResource:#"activeimage" ofType:#"png"];
NSString* imgInactive = [[NSBundle mainBundle] pathForResource:#"inactive" ofType:#"png"];
for (NSUInteger subviewIndex = 0; subviewIndex < [self.subviews count]; subviewIndex++)
{
UIImageView* subview= [self.subviews objectAtIndex:subviewIndex];
if (subviewIndex == page)
[subview setImage:[UIImage imageWithContentsOfFile:imgActive]];
else
[subview setImage:[UIImage imageWithContentsOfFile:imgInactive]];
subview.frame = CGRectMake(subview.frame.origin.x, subview.frame.origin.y, 10,10);
}
}
- (void) setNumberOfPages:(NSInteger)pages
{
NSLog(#"setNumberOfPages");
[super setNumberOfPages:pages];
NSString* img = [[NSBundle mainBundle] pathForResource:#"inactive" ofType:#"png"];
for (NSUInteger subviewIndex = 0; subviewIndex < [self.subviews count]; subviewIndex++)
{
UIImageView* subview= [self.subviews objectAtIndex:subviewIndex];
[subview setImage:[UIImage imageWithContentsOfFile:img]];
subview.frame = CGRectMake(subview.frame.origin.x, subview.frame.origin.y, 10,10);
}
}
Already i'm having one view with pagecontrol and scrollview...Here what i'm doing is select the uipagecontroller from nib and choose identity inspector and select the class name PageControl(newly created class with 2 methods)it works for changing the color while swipe the images but,it didn't works for clicking the pagecontrol for moving to next page...
I don't know what shoud i want to include or what mistake i'm doing...please help me out to do this...
Thank You...
If you want to enable page scrolling on click of dot then you need to first of all associate the "value changed" property in your xib file to the action you set in your code.
I have implemented the same functionality in one of my projects so it will definitely work.
- (IBAction)changePage:(id)sender {
int page = pageControl.currentPage;
CGFloat pageWidth = scrollView.frame.size.width;
pageWidth = scrollView.frame.size.width;
pageControl.currentPage = page;
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
}
Cheers
Your above code is crashing in iOS 7.I have found a solution for this problem. I know it is not the way but Sure that it works till iOS 8 will be launched in the market.
Reason for Crash:
in iOS 7 [self.subViews objectAtIndex: i] returns UIView Instead of UIImageView and setImage is not the property of UIView and the app crashes. I solve my problem using this following code.
Check Whether the subview is UIView(for iOS7) or UIImageView(for iOS6 or earlier). And If it is UIView I am going to add UIImageView as subview on that view and voila its working and not crash..!!
-(void) updateDots
{
for (int i = 0; i < [self.subviews count]; i++)
{
UIImageView * dot = [self imageViewForSubview: [self.subviews objectAtIndex: i]];
if (i == self.currentPage) dot.image = activeImage;
else dot.image = inactiveImage;
}
}
- (UIImageView *) imageViewForSubview: (UIView *) view
{
UIImageView * dot = nil;
if ([view isKindOfClass: [UIView class]])
{
for (UIView* subview in view.subviews)
{
if ([subview isKindOfClass:[UIImageView class]])
{
dot = (UIImageView *)subview;
break;
}
}
if (dot == nil)
{
dot = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, view.frame.size.width, view.frame.size.height)];
[view addSubview:dot];
}
}
else
{
dot = (UIImageView *) view;
}
return dot;
}
Hope this solve ur issue too for iOS7. and If Anypone find the optimal solution for that please comment. :)
Happy coding

Loading Scroll Views from plists

here is the deal: For a news app, I'm loading a view inside a Scroll View for horizontal paging on each section, no problem with that, the PageControl demo helped a lot, but now I need to load a View inside another Scroll View programmatically so I can show the content of each section, the deal is that I need custom designed views already on a NIB file so each section looks different, so I would like to use a plist to load each custom view on the generic Scroll View.
Here is what I got until now:
- (void)loadScrollViewWithPage:(int)page{
if (page < 0)
return;
if (page >= kNumberOfPages)
return;
// replace the placeholder if necessary
Seccion *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
controller = [[Seccion alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
NSDictionary *numberItem = [self.contentList objectAtIndex:page];
//UIImage *image1 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image1.jpg" ofType:nil]];
controller.sectionTitle.text = [numberItem valueForKey:Nombre];
controller.sectionView.text = [numberItem objectForKey:Vista];
controller.sectionId.text = [numberItem valueForKey:Id];
//Here is supposed to have the code to load the view inside the scroll view I tried using: [controller.sectionScrollView addSubview:controller.sectionView.text];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
Thanks a lot in advance
If all your views have it own nib, this might work:
UIView *view = [[[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil] objectAtIndex:0];
so you can save the name of each nib in a plist.

UIView not being positioned with setFrame

I'm probably not doing this correctly. Having not done an iPad app before I'm doing what seems natural to me.
I have a UIView that is going to be made of up other UIViews. Specifically, I want to dynamically create and add subviews to each of these subviews. In other words:
UIView
|
| --> UIView
|
| --> Dynamic UIView 1
| --> Dynamic UIView 2
| --> ...
I managed to get 'Dynamic UIView 1' by adding to its initWithFrame this bit of code to load the xib:
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"ItemView"
owner:[[ItemViewController alloc] init]
options:nil];
ItemView *infoView = [nibViews objectAtIndex:0];
[self addSubview:infoView];
It works! The problem I'm having is that 'Dynamic UIView n' is always rendered at the top left corner of the screen. If I try to change the position with setFrame I get a black box at representing the frame however the actual control content remains in the top left.
Any ideas? Is there a better way to do this?
----- Update -----
Here is a screenshot of the root view.
Overview of main UIView http://www.freeimagehosting.net/uploads/460090996d.png
The entire control is call CurrentItemsViewController. The green area is a UIView within that I have linked back in code via a link in the IB, in the code sample it is called "itemsUIView". Here is how I am adding items within CurrentItemsViewController.m
- (id)init {
[super initWithNibName:nil
bundle:nil];
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"Current"];
/* Approach 1 */
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"ItemView"
owner:[[ItemViewController alloc] init]
options:nil];
ItemView *subItemView1 = [nibViews objectAtIndex:0];
/* Approach 2 - this apprach does Approach 1 in the initWithFrame method */
//ItemView *subItemView1 = [[ItemView alloc] initWithFrame:CGRectMake(120, 120, 354, 229)];
/* Approach 3 */
//ItemViewController *ctr = [[ItemViewController alloc] init];
//UIView *subItemView1 = [ctr view];
[[self view] addSubview:subItemView1];
// [[self itemsUIView] addSubview:subItemView1]; <-- doesn't render subItemView1 at all
[subItemView1 release];
[subItemView1 setFrame:CGRectMake(120, 120, 354, 229)];
[subItemView1 setBounds:CGRectMake(120, 120, 354, 229)];
return self;
}
Inside of ItemView.m I have this, it only gets call by Approach 2 and 3.
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"ItemView"
owner:[[ItemViewController alloc] init]
options:nil];
ItemView *infoView = [nibViews objectAtIndex:0];
[self addSubview:infoView];
}
return self;
}
As shown, I tried creating the ItemView 3 different ways and each one renders the same result. When I add the view as a subview of the root view I get this. Notice that a square appears where it should render, however ViewItem actually renders at the top left corner. In the sample above, when I add subItemView1 it doesn't render anything at all.
alt text http://www.freeimagehosting.net/uploads/c6635ce860.png
Try setting the frame before you add it as a subview.
Your code:
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"ItemView"
owner:[[ItemViewController alloc] init]
options:nil];
ItemView *infoView = [nibViews objectAtIndex:0];
self addSubview:infoView];
Should be:
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"ItemView"
owner:[[ItemViewController alloc] init]
options:nil];
ItemView *infoView = [nibViews objectAtIndex:0];
infoView.frame = CGRectMake( put your rect here );
[self addSubview:infoView];