First off, believe me when I say I have tried all of the suggestions. But I am willing to try them again, so feel free to comment/answer. Currently my code looks like:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = CGRectMake(tblView.frame.origin.x, tblView.frame.origin.y, tblView.frame.size.width, tblView.contentSize.height);
[tblView setFrame:frame];
[tblView reloadData];
CGRect contentRect = CGRectZero;
for (UIView *view in scrollView.subviews)
contentRect = CGRectUnion(contentRect, view.frame);
[scrollView setContentSize:contentRect.size];
scrollView.frame = CGRectMake(scrollView.frame.origin.x, scrollView.frame.origin.y, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
}
My #interface is:
#interface VH_HotelsListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageView;
IBOutlet UITableView *tblView;
NSMutableArray *hotelArray;
}
I have tied my storyboard table view into the tblView above. My table view is populated at run time from my database, so I know there are no issues there.
As you can see from above, I am getting the content size of the table view and trying to adjust the frame to the same height. I am accurately getting the content size, though, because it resizes my scroll view to that height. It just does nothing to the table view, unfortunately. Though if I NSLog(#"Table View Height: %g", tblView.frame.size.height) just after setting it, I get the same number as for the content size Table View Height: 3166. So it's like it's working, but it's not actually expanding it.
Well, I got no answers, so I've updated my project. I've taken the UITableView out of my storyboard altogether and now just create it in code:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
tblView = [[UITableView alloc] initWithFrame:CGRectMake(0, 150, 320, 500) style:UITableViewStyleGrouped];
tblView.dataSource = self;
tblView.delegate = self;
[scrollView addSubview:tblView];
}
Then in viewDidAppear:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = CGRectMake(tblView.frame.origin.x, tblView.frame.origin.y, tblView.frame.size.width, tblView.contentSize.height);
tblView.frame = frame;
[tblView reloadData];
}
This seems to be working.
Related
I want to create another UIView / UIButton on an UIButton so I'm getting its' frame and use it in declaration of another UIView but It creates like below screenshot (with blue view). By the way, button is created on storyboard.
I'm using Xcode 9.1 and iOS 11.1
- (void)viewDidLoad {
UIView *picker = [[UIView alloc] initWithFrame:_mButton.frame];
picker.backgroundColor=[UIColor blueColor];
[self.view addSubview: picker];
}
Screenshot 1
Screnshot 2
I guess the proper frames are not calculated in viewDidLoad. You can try to make picker a property and adjust its frame in viewDidLayoutSubviews
#property (strong, nonatomic) UIView *picker;
- (void)viewDidLoad {
[super viewDidLoad];
self.picker = [[UIView alloc] initWithFrame:_mButton.frame];
self.picker.backgroundColor=[UIColor blueColor];
[self.view addSubview: self.picker];
}
- (void)viewDidLayoutSubviews {
self.picker.frame = _mButton.frame;
[super viewDidLayoutSubviews];
}
But off course using storyboard and autolayout would probably be the best sollution if you have this possibility.
I want to use custom view as a toolbar at bottom of my view controller and then design it in my own way. I am using UIView for this purpose and then add as a subview. Somehow, the height of my custom tool bar is not changing. Even, I turned off constraints for it but somehow, it auto adjusts. How can, I do this? Below is my code snippet.
//CameraActivity.h class
#interface CameraActivity : UIViewController
//Custom UIView.
#property (nonatomic, strong) UIView *toolbar;
#end
//CameraActivity.m class, in viewDidLoad.
_toolbar.translatesAutoresizingMaskIntoConstraints = YES;
[self.view removeConstraints:self.view.constraints];
[_toolbar removeConstraints:_toolbar.constraints];
CGRect frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
_toolbar = [[UIView alloc]initWithFrame:frame];
[_toolbar setBackgroundColor:[UIColor colorWithRed:116.0/255.0 green:174.0/255.0 blue:220.0/255.0 alpha:0.75]];
[self.view addSubview:_toolbar];
Make an outlet of your UIView height constraint. Then try to change its height based on device's type as follow:-
In ViewController.h file, Create an outlet:-
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewHeightConstraint;
In ViewController.m file, Change your height's constraint like this:-
if (Device is iPhone 4s) {
viewHeightConstraint.constant = 30.0; //Your desired height
}
else if (Device is iPhone 5 || Device is iPhone 5s || Device is iPhone 5c) {
viewHeightConstraint.constant = 40.0; //Your desired height
}
else if (Device is iPhone 6) {
viewHeightConstraint.constant = 50.0; //Your desired height
}
else if (Device is iPhone 6 Plus) {
viewHeightConstraint.constant = 60.0; //Your desired height
}
Happy Coding!!
Before creating (i.e _toolbar = [[UIView alloc]initWithFrame:frame];) your view toolbar, using it will cause this issue.
Hence, change the line order to this :
CGRect frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
_toolbar = [[UIView alloc]initWithFrame:frame];
_toolbar.translatesAutoresizingMaskIntoConstraints = YES;
[self.view removeConstraints:self.view.constraints];
[_toolbar removeConstraints:_toolbar.constraints];
[_toolbar setBackgroundColor:[UIColor colorWithRed:116.0/255.0 green:174.0/255.0 blue:220.0/255.0 alpha:0.75]];
[self.view addSubview:_toolbar];
Also I suggest setting frame must done in
-(void) viewDidLayoutSubviews beacause viewDidLoad is not a good place for this! so,
-(void) viewDidLayoutSubviews
{
_toolbar.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 44, [[UIScreen mainScreen] bounds].size.width, 150);
}
I added UIView from objects library instead of adding it programmatically and then sets its width according to screen width of device and height to constant. Also assigned some constraints solve my problem.
//CameraActivity.h class
#interface CameraActivity : UIViewController
//This time not custom UIView but IBOutlet.
#property (nonatomic, strong) IBOutlet UIView *toolbar;
#end
//CameraActivity.m class
#import "CameraActivity.h"
#implementation CameraActivity
-(void)viewDidLoad
{
[super viewDidLoad];
//Get your device screen width.
CGFloat width = [UIScreen mainScreen].bounds.size.width;
_toolbar.frame = CGRectMake(0, 44, width, 150);
}
Im wanting to setup my view within the storyboard so it lays out like the above image. The view has 2 seperate sections when landscape the share 50/50 horizontally then when portrait it rotates to 50/50 vertically.
What is the most appropriate way to set this up inside xcode interface builder? Can I use constraints to achieve this? This will need to be designed so it will scale to ipad and iphone as well.
I build a project to test. It works, check the screenshot
iPad in Portrait
iPad in Landscape
It can't be done in Storyboard, because iPad only got one layout in Storyboard.
but it's very simple to achieve what you need programmatically .
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UIView *firstView;
#property (nonatomic, strong) UIView *secondView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.firstView = [[UIView alloc] initWithFrame:CGRectZero];
self.firstView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.firstView];
self.secondView = [[UIView alloc] initWithFrame:CGRectZero];
self.secondView.backgroundColor = [UIColor blueColor];
[self.view addSubview:self.secondView];
[self setupSubViewLayout];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self setupSubViewLayout];
}
- (void)setupSubViewLayout {
CGFloat viewWidth = self.view.frame.size.width;
CGFloat viewHeight = self.view.frame.size.height;
CGRect firstRect;
CGRect secondRect;
if (viewWidth > viewHeight) {
firstRect = CGRectMake(0, 0, viewWidth/2.0, viewHeight);
secondRect = CGRectMake(viewWidth/2.0, 0, viewWidth/2.0, viewHeight);
}else {
firstRect = CGRectMake(0, 0, viewWidth, viewHeight/2.0);
secondRect = CGRectMake(0, viewHeight/2.0, viewWidth, viewHeight/2.0);
}
self.firstView.frame = firstRect;
self.secondView.frame = secondRect;
}
I have a UIView that draws a pie chart and I would like to put 3 or maybe 4 charts in a UIScrollView programatically. How can I do that?
my h file is like this
#class PieChart;
#interface ViewController : UIViewController {
}
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
and m file
- (void)viewDidLoad
{
[super viewDidLoad];
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
PieChart *chart = [[PieChart alloc]initWithFrame:CGRectZero];
[chart setFrame:CGRectMake(100, 100, 200, 200)];
[scrollView addSubview:chart];
}
If you need to add subview to the view you need to use [view addSubview:subview]. This is common practice.
Read about frames and bounds (coordinate systems for view and sub views):
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaViewsGuide/Coordinates/Coordinates.html
As I understand you have a problem due to content size of scroll view. Read more here:
http://developer.apple.com/library/ios/#DOCUMENTATION/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html
Hope it helps.
You can just add it with:
[scrollView addSubview:singleView];
You add multiple subviews to a UIScrollView just like you add a single subview; with addSubview:. What problems are you running into?
In my app, I have a split screen in which the detail view is a scrollview. I have 5 tables which are subviews of my scrollview in which 3 table views are side by side on top and 2 table views are side by side on bottom
I have already implemented a way in which when I click any of the rows of any of the table in the scrollview, that view disappears and another view zooms into its position.
I write the following code in the didSelectRowAtIndexPath in the middle table subview,
CGFloat xpos = self.view.frame.origin.x;
CGFloat ypos = self.view.frame.origin.y;
self.view.frame = CGRectMake(xpos+100,ypos+150,5,5);
[UIView beginAnimations:#"Zoom" context:NULL];
[UIView setAnimationDuration:2];
self.view.frame = CGRectMake(xpos,ypos,220,310);
[UIView commitAnimations];
[self.view addSubview:popContents.view];
popContents is the view I need to zoom into to the view previously occupied by that particular table view and that happens correctly.
However the problem that I am facing is that since there is another table subview in the side, if I increase the frame size to say 250 or so, the part of the zoomed in view gets hidden by the tableview on the side ( as its as if a part of the zoomed in view goes under the tableview on the side).
Is there anyway to correct this so that my zoomed in view would not get hidden by the tableviews on its sides?
I hope I have explained my problem correctly...
UPDATE:
Here is the code I am using for adding the subviews for the scrollview
// Scroll view
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 30, 1000, 740)];
scrollView.contentSize = CGSizeMake(1000, 700);
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
[self.view addSubview:scrollView];
aView = [[aViewController alloc] initWithNibName:#"aViewController" bundle:nil];
aView.view.frame = CGRectMake(10, 25, 220, 310);
[aView loadList:objPatients];
[scrollView addSubview:aView.view];
bView = [[bViewController alloc] initWithNibName:#"bViewController" bundle:nil];
bView.view.frame = CGRectMake(10, 350, 220, 310);
[bView loadList:objPatients];
[scrollView addSubview:bView.view];
cView = [[cViewController alloc] initWithNibName:#"cViewController" bundle:nil];
cView.view.frame = CGRectMake(240, 25, 220, 310);
[cView loadList:objPatients];
[scrollView addSubview:cView.view];
dView = [[dViewController alloc] initWithNibName:#"dViewController" bundle:nil];
enView.view.frame = CGRectMake(240, 350, 220, 310);
[enView loadList:objPatients];
[scrollView addSubview:dView.view];
eView = [[eViewController alloc] initWithNibName:#"eViewController" bundle:nil];
eView.view.frame = CGRectMake(470, 25, 220, 310);
[eView loadList:objPatients];
[scrollView addSubview:eView.view];
say for example, I add the code for didSelectRowAtIndexPath in cViewController subview...
This is a guess since I would need to know how your table views are added to the scroll view, but the middle table view was probably added before the one on the side. Views are "stacked" in the order they're added with the last one on top. You'll need to get the scroll view to move the middle view to the front with this method
- (void)bringSubviewToFront:(UIView *)view
The best way to do that would be to create a protocol for the table views and make the scroll view the delegate. The method would be something like this
- (void) moveAViewToFront: (MyTableView *) aTableView
{
[self.view bringSubviewToFront: aTableView.view];
}
You would then call the delegate method before setting up the animation.
Edited
After a little more thought I realized that the subviews have a reference to their superview so this bit of code should provide an idea on how to solve the problem. I created a test app which has a view controller which adds two sub views. The view controller header file is MoveSubviewViewController.h
#import <UIKit/UIKit.h>
#interface MoveSubviewViewController : UIViewController
{
}
#end
and it's implementation is
#import "MoveSubviewViewController.h"
#import "MoveableSubview.h"
#implementation MoveSubviewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Create two overlapping subviews. The blue subview will start at the top of
// the frame and extend down two thirds of the frame.
CGRect superviewFrame = self.view.frame;
CGRect view1Frame = CGRectMake( superviewFrame.origin.x, superviewFrame.origin.y,
superviewFrame.size.width, superviewFrame.size.height * 2 / 3);
MoveableSubview *view1 = [[MoveableSubview alloc] initWithFrame: view1Frame];
view1.backgroundColor = [UIColor blueColor];
[self.view addSubview: view1];
[view1 release];
// The green subview will start one third of the way down the frame and
// extend all the to the bottom.
CGRect view2Frame = CGRectMake( superviewFrame.origin.x,
superviewFrame.origin.y + superviewFrame.size.height / 3,
superviewFrame.size.width, superviewFrame.size.height * 2 / 3);
MoveableSubview *view2 = [[MoveableSubview alloc] initWithFrame: view2Frame];
view2.backgroundColor = [UIColor greenColor];
[self.view addSubview: view2];
[view2 release];
}
#end
The subview class is MoveableSubview with another simple header
#import <UIKit/UIKit.h>
#interface MoveableSubview : UIView
{
}
#end
and implementation
#import "MoveableSubview.h"
#implementation MoveableSubview
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Move this view to the front in the superview.
[self.superview bringSubviewToFront: self];
}
#end
The thing to do is to add the
[self.superview bringSubviewToFront: self];
line before setting up the animation.