I have a UIScrollView (similar to that seen showing the featured items on the App Store) which has 3 views, with xibs, loaded into it. Everything works find except I can get the UIButtons which I have on the xibs to fire. I guess I am missing something obvious just can't see it. I've tried various answers on here and other places to no avail.
Thanks in advance
Code from viewDidLoad on ViewController containing scroll view
LSCWInfoView *view1 = [[[NSBundle mainBundle]
loadNibNamed:#"LSCW-InfoView"
owner:self options:nil]
firstObject];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = self.activityPageControl.frame.size;
[view1 setFrame:frame];
[self.activityScrollView addSubview:view1];
ScrambledInfoView *view2 = [[[NSBundle mainBundle]
loadNibNamed:#"Scrambled-InfoView"
owner:self options:nil]
firstObject];
CGRect frame2;
frame2.origin.x = 320;
frame2.origin.y = 0;
frame2.size = self.activityPageControl.frame.size;
[view2 setFrame:frame2];
[self.activityScrollView addSubview:view2];
TestInfoView *view3 = [[[NSBundle mainBundle]
loadNibNamed:#"Test-InfoView"
owner:self options:nil]
firstObject];
CGRect frame3;
frame3.origin.x = 640;
frame3.origin.y = 0;
frame3.size = self.activityPageControl.frame.size;
[view3 setFrame:frame3];
[self.activityScrollView addSubview:view3];
_activityScrollView.contentSize = CGSizeMake(_activityScrollView.frame.size.width * 3, _activityScrollView.frame.size.height);
EDIT - Code for one of the views loaded into the scroll view (other 2 are the same)
#import "LSCWInfoView.h"
#implementation LSCWInfoView
- (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
}
*/
- (IBAction)lscwPlayButtonPressed:(id)sender
{
NSLog(#"YEP");
}
#end
Screenshots
This was fixed by setting the frame size of the view before it is added to the scrollview
Related
I have UIViewcontroler which occupied with two component one UITableView of the size Width: 120 and Height:603 of UIViewcontroller and another one UIView (detailView) related screen. (size Width: 255 & Height: 603 )
Now I created on custom UIView (customView) now I want to added it on detailView, which is not fit to UIView
detailView Frame is half of uiviewcontroller view size.
the custom view frame is normal i.e width 375 & height 667
-(void)loadView {
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:nil];
customView = [nibObjects objectAtIndex:0];
customView.frame = detailView.frame;
customView.layer.shadowColor = [UIColor blackColor].CGColor;
customView.layer.shadowRadius = 1.0f;
customView.layer.shadowOpacity = 1;
customView.layer.shadowOffset = CGSizeZero;
customView.layer.masksToBounds = YES;
[detailView addObject:customView];
}
The CustomView is not auto adjusted on the detailView UIView Screen.
Your advice will be useful for understand to fix frame
#Thanks in advance
The problem is you are setting the detailView's frame to your customView and adding the customView into your detailView.
to set the frame of your custom view please use below code:
customView.frame = (CGRect){
.origin = CGPointZero,
.size = detailView.frame.size
};
Hope fully this will solve your problem.
Your loadView Method is written like below
-(void)loadView {
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:nil];
customView = [nibObjects objectAtIndex:0];
customView.frame = CGRectMake(0, 0, detailView.frame.size.width, detailView.frame.size.height);
customView.layer.shadowColor = [UIColor blackColor].CGColor;
customView.layer.shadowRadius = 1.0f;
customView.layer.shadowOpacity = 1;
customView.layer.shadowOffset = CGSizeZero;
customView.layer.masksToBounds = YES;
[detailView addSubview:customView];
}
I am having huge problems with learning autolayout especially when integrating xibs and uiscrollviews. In an effort to simplify my problem, I started a new project with a single view tied to a storyboard. I then subclassed UIView (Diptic) and created a xib file for it. My storyboard is not using autolayout, but my Diptic xib is. Right now I want to have a horizontal scrollView with a few Diptic instances layed out across it. But I am only ever getting the first diptic instance to show up, because the frame isn't being initialized correctly.
In my ViewController.m's viewDidLoad:
self.scrollView.contentSize = CGSizeMake((self.view.frame.size.width+10)*5, self.view.frame.size.height);
for (int i = 0; i < 5; i++){
int x = i*(self.view.frame.size.width+10);
Diptic *diptic = [[Diptic alloc] initWithFrame:CGRectMake(x, 50, self.view.frame.size.width, self.view.frame.size.height-100)];
[self.scrollView addSubview:diptic];
[array addObject:diptic];
UIView *greenBox = [[UIView alloc] initWithFrame:CGRectMake(x, 5, 40, 40)];
greenBox.backgroundColor = [UIColor greenColor];
[self.scrollView addSubview:greenBox];
}
Diptic.m
#import "Diptic.h"
#implementation Diptic
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"Diptic" owner:nil options:nil];
self = [views objectAtIndex:0];
self.label.text = #"WOOT";
self.backgroundColor = [UIColor redColor];
}
return self;
}
#end
If I set the frame after I add it to the view it seems to work, but why can't I set the frame with initWithFrame?
The problem here is that you assign the frame to a view that is created with a call to [super initWithFrame:frame]. When the NIB is loaded in - (id)initWithFrame:(CGRect)frame, self is replaced with a view from [views objectAtIndex:0] and the frame for this view is never set. Instead, eliminate the call to super and load the view from the NIB instead:
#import "Diptic.h"
#implementation Diptic
- (id)initWithFrame:(CGRect)frame
{
NSArray *views = [[NSBundle mainBundle] loadNibNamed:#"Diptic" owner:nil options:nil];
self = [views objectAtIndex:0];
if (self) {
self.frame = frame;
self.label.text = #"WOOT";
self.backgroundColor = [UIColor redColor];
}
return self;
}
#end
When init a view/controller from storyboard or from xib, the init method is
- (id)initWithCoder:(NSCoder *)decoder
try to do other things in this method
I've created a UIScrollView programatically, and it is not scrolling:
CGRect prevFrame;
BOOL isFirst = TRUE;
UIScrollView *view_scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
view_scroll.contentSize = CGSizeMake(650,224*[_cases count]+25*[_cases count]);
view_scroll.showsVerticalScrollIndicator = YES;
view_scroll.scrollEnabled = YES;
NSLog(#"%f",view_scroll.contentSize.height);
[self.view addSubview:view_scroll];
for(SLSCase* patientCase in _cases){
SLSCaseCard* caseCard = [[[NSBundle mainBundle] loadNibNamed:#"SLSCaseCard" owner:self options:nil] objectAtIndex:0];
if(isFirst){
caseCard.frame = CGRectMake(25,25, caseCard.frame.size.width, caseCard.frame.size.height);
isFirst = FALSE;
}
else{
caseCard.frame = CGRectMake(25, prevFrame.origin.y+caseCard.frame.size.height+25, caseCard.frame.size.width, caseCard.frame.size.height);
}
prevFrame = caseCard.frame;
[view_scroll addSubview:caseCard];
}
As you can see I've set the contentSize and scrollEnabled. It's still not scrolling.
Due to a scrollView feature in auto layout, the contentSize is being redefined. To solve this problem, you could disable auto layout or set the content size in viewDidLayoutSubviews()
-(void)viewWillLayoutSubviews {
[super viewDidLayoutSubviews];
view_scroll.contentSize = CGSizeMake(650,224*[_cases count]+25*[_cases count]);
}
I created a UIView subclass associated with .xib file. This UIView subclass is to be used in a UIViewController. In the controller, I think there are two options how we instantiate the UIView subclass:
MyUIView *myView=[[MyUIView alloc] initWithFrame:aRect];
and
MyUIView *myView = [[[NSBundle mainBundle] loadNibNamed:#"MyUIView"
owner:self
options:nil] lastObject];
I prefer the first approach or its variants that allow me to perform custom initialization. The only problem is that I have to specify a frame's rect, which was already specified in .xib (I mean frame's height and width of MyUIView). Yes, I can hardcode it again in aRect, but this is tedious to maintain (e.g., when I change position of UIs in .xib, I have to update aRect, too).
So the second approach should come into mind as the frame rect is automatically set. The remaining problem is I cannot customize the initializer (say, I want to pass extra parameters during initialization).
What's your preference? Which one is better in your opinion?
EDIT1:
Inspired by sergio's answer, I came out with this workaround:
// In MyViewController.m
MyUIView *myView=[[MyUIView alloc] initWithFrame:CGRectMake(x, y, 0.0, 0.0)];
// In MyView.m
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self = [[[NSBundle mainBundle] loadNibNamed:#"UnmovableTagView"
owner:self
options:nil] lastObject];
[self setFrame:CGRectMake(frame.origin.x,
frame.origin.y,
[self frame].size.width,
[self frame].size.height)];
// frame's width and height already determined after
// loadNibNamed was called
...
}
return self;
}
Have you tried using:
MyUIView *myView=[[MyUIView alloc] initWithFrame:CGRectZero];
I don't know if it works in your case (loading the view from a nib), but I use it successfully when I create my custom view programmatically.
You can give it a try.
EDIT:
you could define your own init method for your view:
-(id)initWithPosition:(CGPoint)pos;
and then call:
-(id)initWithPosition:(CGPoint)pos {
if (self = [super initWithFrame:{pos,{0,0}}]) {
self = [[[NSBundle mainBundle] loadNibNamed:#"UnmovableTagView"
owner:self
options:nil] lastObject];
[self setFrame:CGRectMake(frame.origin.x,
frame.origin.y,
[self frame].size.width,
[self frame].size.height)];
// frame's width and height already determined
// after loadNibNamed was called
}
I want to position a view (red box with label and button) prepared in IB as Subview on the screen programmatically. The positioning works fine with the "blue lines" (there might actually be a better way to simply draw a line on a view?!). But the view of the "AttributeApertureView" view object sticks to the top instead of following the initFrame Parameter starting at y=60 as you can see in the screenshot.
//Add blue Line
CGRect lineB = CGRectMake(0, 48, bounds.size.width, 0.5);
UIView *secondLine = [[UIView alloc]initWithFrame:lineB];
[secondLine setBackgroundColor:[UIColor colorWithRed:0.396 green:0.796 blue:0.894 alpha:1]];
[[self view]addSubview:secondLine];
//Add Attribute Aperture
AttributeApertureView *aperture = [[AttributeApertureView alloc]initWithFrame:CGRectMake(0, 60, bounds.size.width, 50)];
[aperture setBackgroundColor:[UIColor redColor]];
[[self view]addSubview:aperture];
Init function in AttributeApertureView class. This should basically only load the related nib file with the IB Interface.
#implementation AttributeApertureView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"AttributeApertureView"
owner:self
options:nil];
self = [nib objectAtIndex:0];
}
return self;
}
What is the best way to position the "aperture" view on the screen?
Seems like calling loadNibNamed: resets the view's frame to what it is in the nib. This should work:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"AttributeApertureView"
owner:self
options:nil];
self = [nib objectAtIndex:0];
self.frame = frame;
}
return self;
}
because self = [super initWithFrame:frame]; sets the frame once, but self = [nib objectAtIndex:0]; ends up changing it again because you are resetting the whole view, so you have to set the frame again to be the one in the argument.