enter image description hereWhen i add three imageViews to scrollView, and i setting scrollView contentSize is three times scrollView's width, even if it was appeared in scrolView,but imageView's width not equal to scrollview's. I ensured that already setting they width equeal to each otehr. If who know that how to resolve this issue,please help me, thinks.
- (void)addScrollViewImage {
for (NSInteger index = 0; index < IMAGE_NUM; index++) {
UIImageView *imageView = [[UIImageView alloc] init];
CGFloat imageViewX = index * (self.scrollView.frame.size.width);
imageView.frame = CGRectMake(imageViewX, 0, self.scrollView.frame.size.width , self.scrollView.frame.size.height);
imageView.image = [UIImage imageNamed:#"搜索图片"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.scrollView addSubview:imageView];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * IMAGE_NUM, self.scrollView.frame.size.height);
}
you need to change imageview content mode
imageView.contentMode = UIViewContentModeScaleAspectFill;
With
imageView.contentMode = UIViewContentModeScaleToFill;
This is because when your viewController is loaded, view / scrollView frame is still unknown.
You need to override viewDidLayoutSubviews() and setup children frames and content size there.
Important note: iOS is adding EXTRA UIImageView's for scroll indicators. That's why you can't use scrollView.subviews.count inside viewDidLayoutSubviews(), but you can use IMAGE_NUM though.
Some Swift code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let scrollSize = scrollView.bounds.size
var frame = scrollView.bounds
// Wrong: for i in 0 ..< scrollView.subviews.count
for i in 0 ..< IMAGE_NUM {
let view = scrollView.subviews[i]
view.frame = frame
frame.origin.x += scrollSize.width
}
scrollView.contentSize = CGSize(width: frame.origin.x, height: scrollSize.height)
}
Related
I have place UIImageView under UIScrollView on screen with constant width same as screen, and it works fine in iphone 5s but on iphone 7 or 8 the size of image is less than the width of screen size as shared on screenshots.
here is my code:
let x = CGFloat(selectedEvent.album?.count ?? 0)
pageControl.numberOfPages = (selectedEvent.album?.count ?? 0)
for index in 0..<(selectedEvent.album?.count ?? 0) {
frame.origin.x = scroll.frame.size.width * CGFloat(index)
frame.size = scroll.frame.size
print(self.frame.size.width)
print(scroll.frame.size.width)
print(frame.size.width)
let image = UIImageView(frame: frame)
image.contentMode = .scaleToFill
print(image.frame.size.width)
if (selectedEvent.album?.count ?? 0) > 0 {
selectedEvent.getAlbumImage(key: selectedEvent.album![index], completion: { (gotImage:UIImage) in
image.image = gotImage
})
} else {
image.image = UIImage(named: "defaultImage.jpg")
}
scroll .addSubview(image)
}
self.scroll.contentSize = CGSize(width: scroll.frame.size.width * x, height: scroll.frame.size.height)
pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)
here is the Print Log
320.0
320.0
320.0
320.0
320.0
320.0
320.0
320.0
In shorts, views might not have updated frames on viewDidLoad or ViewWillAppear methods instead views are initialised with storyboard sizes. So you are not getting updated rect for iPhone 7 or other devices.
Another reason is scrollview adjusts it's subview automatically. So disable it on viewDidLoad().
override func viewDidLoad() {
super.viewDidLoad()
self.scroll.contentInsetAdjustmentBehavior = .never;
// write your code
}
You should add subviews on viewDidLoad() method as you have done already and update frame & scrollview content related changes on viewDidLayoutSubviews().
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews();
for view:UIView in self.scroll.subviews {
frame.origin.x = self.scroll.frame.size.width * CGFloat(self.scroll.subviews.index(of: view)!);
frame.size = scroll.frame.size
view.frame = frame;
}
self.scroll.contentSize = CGSize(width: scroll.frame.size.width * selectedEvent.album?.count , height: scroll.frame.size.height)
}
Hope will work.
You want the frame width to be the screen width. Use as :
let size = UIScreen.main.bounds.size
self.scroll.contentSize = CGSize(width: size.width, height: scroll.frame.size.height)
I have an UIView and add an UIScrollView to it. Inside the scrollView is an UIImageView.
I want to zoom the image view by pressing a button. If the image view is zoomed you should be able to scroll but that's not working.
Currently I have that:
self.imageView = UIImageView()
self.imageView.image = image
self.imageView.frame = self.contentView.bounds
self.scrollView = UIScrollView()
self.scrollView.frame = self.contentView.bounds
self.scrollView.contentSize = self.contentView.bounds.size
self.scrollView.addSubview(self.imageView)
self.contentView.addSubview(self.scrollView)
and that:
#IBAction func zoomPicture() {
if (scale <= 1.5) {
scale = scale + 0.1
scrollView.transform = CGAffineTransformMakeScale(scale, scale)
scrollView.zoomScale = scale
scrollView.maximumZoomScale = 1.5
scrollView.minimumZoomScale = 1.0
scrollView.contentSize = contentView.bounds.size
scrollView.scrollEnabled = true
}
}
my class also implements UIScrollViewDelegateand I set the delegate in the viewDidLoad() function. I have also added the viewForZoomingInScrollView function. The zoom works but I can't scroll.
For this issue you have to set self.scrollView.contentSize bigger than self.contentView.bounds so it get proper space to scroll.
replace this line
self.scrollView.contentSize = self.contentView.bounds.size
to this:
self.scrollView.contentSize = self.contentView.bounds.size*2 //or what ever size you want to set
Try this:
#IBAction func zoomPicture() {
if (scale <= 1.5) {
scale = scale + 0.1
scrollView.zoomScale = scale
scrollView.maximumZoomScale = 1.5
scrollView.minimumZoomScale = 1.0
let size = contentView.bounds.size
scrollView.contentSize = CGSize(width: size.width * scale, height: size.height * scale)
scrollView.scrollEnabled = true
}
}
I created a sample app here: https://github.com/steffimueller/LTNavigationBar-TestProject
When you pull down the table at the top above the image a white background appears. This should not be the case. The header image should always be bound at the top of the screen. Here is how it looks in my case:
and here is how it should look like:
The former screenshot is from this app using the parallax branch of the git repo. It is the first tab in the parallax demo which has the effect I want.
Here is the code I use to create the table:
class Page1ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var topView:UIView!
var topImageView: UIImageView?
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Cancel, target: self, action: "sdfsdf"), animated: true)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellIndentifier)
self.navigationController?.navigationBar.lt_setBackgroundColor(UIColor.clearColor())
tableView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleWidth
topView = UIView(frame: CGRectMake(0, 0, 320, 212))
topView.contentMode = UIViewContentMode.ScaleToFill
topView.autoresizesSubviews = true
topView.backgroundColor = UIColor.yellowColor()
topView.clipsToBounds = true
tableView.tableHeaderView = topView
let img = UIImage(named: "bg")
topImageView = UIImageView(image: img)
topImageView?.frame = CGRectMake(0, -89, UIScreen.mainScreen().bounds.size.width, 307)
topImageView?.contentMode = UIViewContentMode.ScaleToFill
topView.addSubview(topImageView!)
}
func scrollViewDidScroll(scrollView: UIScrollView) {
let color: UIColor = UIColor(red: 0/255, green: 175/255, blue: 240/255, alpha: 1)
let offsetY:CGFloat = scrollView.contentOffset.y
if offsetY > NAVBAR_CHANGE_POINT {
let alpha:CGFloat = 1 - ((NAVBAR_CHANGE_POINT + 64 - offsetY) / 64)
self.navigationController?.navigationBar.lt_setBackgroundColor(color.colorWithAlphaComponent(alpha))
}
else {
self.navigationController?.navigationBar.lt_setBackgroundColor(color.colorWithAlphaComponent(0))
}
if offsetY < 0 {
let progress:CGFloat = fabs(offsetY) / 300
self.topImageView?.transform = CGAffineTransformMakeScale(1 + progress, 1 + progress)
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tableView.snp_makeConstraints { (make) -> Void in
make.top.equalTo(self.view).offset(-64)
}
}
}
Edit: I don't want to set tableView.bounces = false.
How can I stick the TableHeader Image always on top of the Screen like in my second screenshot?
There are lots of ways to do this.
Do you want the topView to scroll with the table view? If so, instead of adding the topView as a subview, just assign it to the table view's tableHeaderView property.
Don't want it to scroll? Add the topView to the view controller's view, not the table view. Then position the table view below the top view in the nib/storyboard.
Want the table view to scroll over the image view as the user scrolls down? Put the image view behind the table view, make the table view transparent, and make the table view's contentInset start the first cell below the image.
I'm guessing just messing with the contentInset's top value will get you what you want here.
It's not clear why both the topView and the topImageView are needed. It looks like just the topImageView would be sufficient.
Just add a frame to your tableView like this:
self.tableView.frame=CGRectMake(0, YYY, 320, 307)
where YYY is the Y position you want the table to be positioned at
UPDATE:
Based on your updated question, if you want to have the image appear to be "stuck' to the top of the tableview, even when the user pulls the table down, you need to use the bounds of the tableView to set the frame of your image. Use something like this to set the image frame:
UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, 100.0f+self.tableView.bounds.size.height)];
[self.tableView addSubview:myImage];
You need to make sure your image is larger then the visible headerView so it will continue to show as the user pulls the table down.
The "100.0f+" part is just adding height to the image so it will show
into the headerView, adjust this to fit your image and tableView
header.
UPDATE 2
- (void)viewDidLoad {
[super viewDidLoad];
self.myTableView.delegate=self;
self.myTableView.dataSource=self;
UIImageView *myImageView=[[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.myTableView.bounds.size.height, self.view.frame.size.width, 300.0F+self.myTableView.bounds.size.height)];
[myImageView setClipsToBounds:TRUE];
[myImageView setImage:[UIImage imageNamed:#"myImage.jpg"]];
[self.myTableView addSubview:myImageView];
}
You have to use the following in viewDidLoad():
topView = UIView(frame: CGRectMake(0, 0, 320, 300))
let testView = UIView(frame: CGRectMake(0, 0, 320, 200))
testView.backgroundColor = UIColor.clearColor()
tableView.tableHeaderView = testView
let img = UIImage(named: "bg")
topImageView = UIImageView(image: img)
topImageView?.frame = CGRectMake(0, 0, 320, 180)
topView.addSubview(topImageView!)
topImageView?.contentMode = UIViewContentMode.ScaleToFill
tableView.addSubview(topView!)
tableView.sendSubviewToBack(topView!)
Try by adding an ImageView just below the UITableView(background color should be clearColor) and setting the
yourTableView.contentInset = UIEdgeInsetsMake(100.0, 0.0, 0.0, 0.0).
If you want to bound the UIImage to top of the screen then do the following things. Disable Bounce property of UITableView. you can disable that property from xib or programmatically as well. here i write the code for disable Bounce property programmatically in swift.
self.tableView.bounces = false
Hope this help you.
What i did in my case is to use tableHeaderView instead of section header like, myTableView.tableHeaderView = myImageView
and then in scrollViewDidScrollMethod,
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0
{
scrollView.layoutIfNeeded()
var headerFrame = myTableView.tableHeaderView?.frame
headerFrame?.origin.y = scrollView.contentOffset.y
headerFrame?.size.height = headerHeight-scrollView.contentOffset.y //headerHeight is a constant for actual height of header on storyboard
myTableView.tableHeaderView?.frame = headerFrame!
}
}
Hope this helps in your case
I have a ScrollView combined with a PageControll and it contains 5 images which I want them to scroll. My problem is that the ScrollView width even if it is 320 in simulator it doesn't show covering the all width.
This is my code:
override func viewDidLoad() {
super.viewDidLoad()
images.append(UIImage(named: "one.jpg")!)
images.append(UIImage(named: "two.jpg")!)
images.append(UIImage(named: "three.jpg")!)
images.append(UIImage(named: "four.jpg")!)
images.append(UIImage(named: "five.jpg")!)
for var i = 0; i < images.count; i++ {
var frame: CGRect = CGRectMake(0, 0, 0, 0)
frame.origin.x = self.scrollView.frame.size.width * CGFloat(i)
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
var imageView: UIImageView = UIImageView(frame: frame)
imageView.image = images[i]
self.scrollView.addSubview(imageView)
}
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * CGFloat(images.count), scrollView.frame.size.height)
}
Most likely, the scroll view's width is the correct size, but the content-mode of the UIImageView is set incorrectly such that as a result of the image being displayed having a smaller size than the scroll view, it will not fill the whole of the image view as you wanted.
imageView.contentMode = UIViewContentModeScaleAspectFill;
// Swift
imageView.contentMode = .ScaleAspectFit
Try adding constraints to your image in your interface builder.
Put Constraints:
Main.storyboard -> UIImageView (for each UIImageView) -> Editor -> Pin -> Select leading,top space, bottom and trailing space to superview.
Your scrollView doesn't have constraints
I'm trying to center my subview with a button in itssuperview. So I want the center of the subview be the center of the superview. I'm trying that with following code:
override func viewDidLoad() {
self.view.backgroundColor = UIColor.redColor()
var menuView = UIView()
var newPlayButton = UIButton()
//var newPlayImage = UIImage(named: "new_game_button_5cs")
var newPlayImageView = UIImageView(image: UIImage(named: "new_game_button_5cs"))
newPlayButton.frame = CGRectMake(0, 0, newPlayImageView.frame.width, newPlayImageView.frame.height)
newPlayButton.setImage(newPlayImage, forState: .Normal)
newPlayButton.backgroundColor = UIColor.whiteColor()
menuView.center = self.view.center
menuView.center = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2)
menuView.backgroundColor = UIColor.whiteColor()*/
menuView.addSubview(newPlayButton)
}
Unfortunately it doesent seem to work as this is the result:
UIView *subview = your View To Be Centered In Its SuperView;
UIView *superView = subview.superview;
subview.center = [superView convertPoint:superView.center
fromView:superView.superview];
If view is nil(on fromView:), this method instead converts from window base coordinates. Otherwise, both view and the receiver must belong to the same UIWindow object.
NOTE: If you use the auto layout stuff, then you have to change the constraints . not the frame or center.
Good Luck :)
Try removing your view width from your superview width, e.g.:
var width: CGFloat = (self.view.bounds.size.width / 2)
// (here goes your view width that you want centralize)
menuView.center = CGPointMake(width, self.view.bounds.size.height / 2)
My working code
vRate = superview
rcRating = view ( that I want to centralize in vRate )
self.rcRating = AMRatingControl(location: CGPoint(x: 0, y: 0), andMaxRating: 5)
self.vRate.addSubview(self.rcRating)
var width: CGFloat = (self.vRate.bounds.size.width / 2) - self.rcRating.bounds.size.width
self.rcRating.center = CGPointMake(width, self.vRate.bounds.size.height / 2)