iOS 8 Swift - ScrollViewer and Autolayout content out of screen - ios

I'm trying to make a scroll view on iOS with Swift and Autolayout, but the screen crop the content instead of resizing it.
My layout and constraints
How can i fix this ?
EDIT : Tried with UITextView it doesn't work too
EDIT 2 : I'm trying to make a screen like that and my problem is that i can't implements this screen for all screens resolution and rotation with AutoLayout

I found a solution !
Use Interface Builder only to add a UIScrollView and add constraints to fit superview, and create all subviews programatically.
Override updateViewConstraints()and for each view in the ScrollView set translatesAutoresizingMaskIntoConstraints to false and add a width constraint to keep scrollview width. Dont forget to call super.updateViewConstraint().
Override didRotateFromInterfaceOrientation() and viewDidAppear() and set scrollView.contentSize.height to wrap all items (if you don't do that, you can't scroll).
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var constraintsUpdated = false;
var label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
label.numberOfLines = 0
label.textColor = UIColor.blackColor()
scrollView.addSubview(label)
}
override func updateViewConstraints() {
if(constraintsUpdated){
//Rotate, just update view and keep constraints
super.updateViewConstraints()
scrollView.layoutSubviews()
return;
}
var viewsDictionary = ["label": label, "scrollView": scrollView]
let screenWidth = self.view.frame.width
label.setTranslatesAutoresizingMaskIntoConstraints(false)
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(String(format: "H:[label(==scrollView)]", screenWidth), options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary))
constraintsUpdated = true
super.updateViewConstraints()
//Update subviews
scrollView.layoutSubviews()
}
override func viewDidAppear(animated: Bool) {
scrollView.contentSize.height = label.bounds.height
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
scrollView.contentSize.height = label.bounds.height
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I found another solution with FLKAutoLayout library, that's work great with less code!
class ViewController: UIViewController {
var labelTitle: UILabel = UILabel()
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
//TITLE
scrollView.addSubview(labelTitle)
labelTitle.textColor = UIColor.blackColor()
labelTitle.numberOfLines = 0
//constraints
labelTitle.constrainWidthToView(self.view, predicate: nil)
labelTitle.numberOfLines = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLayoutSubviews() {
scrollView.contentSize.height = labelTitle.frame.height
}
}
I don't know if it's a UIScrollView bug with AutoLayout or a feature

Related

Swift 3 UIScrollview not asking zooming

This is driving me nuts!
I'm basing my UIScrollView on http://koreyhinton.com/blog/uiscrollview-crud.html to make it programatic, so have set up a container view inside my scrollview. But it pans, but won't zoom.
class BinaryTreeViewController: UIViewController, UIScrollViewDelegate {
var scrollView: UIScrollView!
var containerView : UIView!
override func viewDidLoad() {
super.viewDidLoad()
let width:CGFloat = self.view.bounds.width
let height:CGFloat = self.view.bounds.height
scrollView = UIScrollView()
scrollView.delegate = self
scrollView.minimumZoomScale = 0.5
scrollView.maximumZoomScale = 2.0
scrollView.contentSize = CGSize(width: width*2, height: 2000)
scrollView.backgroundColor = .red
containerView = UIView()
scrollView.addSubview(containerView)
view.addSubview(scrollView)
containerView.isUserInteractionEnabled = true
scrollView.isUserInteractionEnabled = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
containerView.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)
}
override func viewWillLayoutSubviews() {
//I create a view called "theView"
containerView.addSubview(theView)
}
The following functions do not fire at any point
func update(zoomScale: CGFloat, offSet: CGPoint) {
scrollView.zoomScale = zoomScale
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return containerView
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
NSLog("scroll")
}
You really don't need to do so much code for that purpose.
You can set up all you need for scrollView in storyboard, and you only need outlet for the view you wish to zoom.
Set up a controller, add scrollview, connect delegate property to view controller, add zooming view as subview in IB.
In the class, conform controller to UIScrollViewDelegate, and use viewForZooming, a scrollView delegate method.
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var zoomer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return zoomer
}
}
P.S. Use newer resources for learning, Ray Wenderlich, AppCoda, etc - its a big web full of good sources, and Swift is in constant change.

UITableView in UIScrollView with activated paging enabled in Swift

I have a question to use UITableView in xib file attaching to UIScrollView with checked paging enabled.
I am not native speaker in english, so please see this carefully.
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var menuScrollView: UIScrollView!
#IBOutlet var pageScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let V1: View1 = View1(nibName: "View1", bundle: nil)
let V2: View2 = View2(nibName: "View2", bundle: nil)
self.addChildViewController(V1)
self.pageScrollView.addSubview(V1.view)
V1.didMoveToParentViewController(self)
self.addChildViewController(V2)
self.pageScrollView.addSubview(V2.view)
V2.didMoveToParentViewController(self)
var V2Frame: CGRect = V2.view.frame
V2Frame.origin.x = self.view.frame.width
V2.view.frame = V2Frame
print("view width:",self.view.frame.width, "v2 origin x:",V2.view.frame.origin.x)
self.pageScrollView.contentSize = CGSizeMake(self.view.frame.width * 2, self.pageScrollView.frame.height)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The first page shows the little bit of second page but I coded ,as shown as above code,
V2Frame.origin.x = self.view.frame.width
I thought this would work to fit width of the view but it doesn't.
I want the View1 and View2 to fit the UIScrollView.
I really appreciate to give me a help.

How to rotate a UILabel upside down in XCode, using Swift?

I would like to have a label that is displayed upside down, when the view did load.
Here is the default code given in the ViewController.swift, and I had also added the UILabel as an outlet.
import UIKit
class ViewController: UIViewController {
#IBOutlet var Label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Also sorry if this is a dumb question I am very new to IOS development and swift.
To rotate your label in viewDidLoad just use the following :
Swift
override func viewDidLoad() {
super.viewDidLoad()
var aLabel: UILabel = ...
aLabel.transform = CGAffineTransformMakeRotation(M_PI)
}
Objective C
-(void) viewDidLoad {
[super viewDidLoad];
UILabel *aLabel = ...
aLabel.transform = CGAffineTransformMakeRotation(M_PI);
}
M_PI will make a rotation of 180 degrees which will result in an upside down label.
Swift 3x, Xcode 8x
override func viewDidLoad() {
super.viewDidLoad()
var aLabel: UILabel = ...
aLabel.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
}
Xcode 8.3.3
override func viewDidLoad() {
super.viewDidLoad()
var aLabel: UILabel = ...
aLabel.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
}

Xcode - Swift - UILabel height expanding for text

I want to make a UILabel's height expand depending on its text.
Here is what the view controller looks like, with the label selected:
Here is the code (I have tried a bunch of different similar things but this is what I have right now):
import UIKit
class ViewControllerTEST: UIViewController {
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label.frame = CGRectMake(0, 0, CGRectGetWidth(label.bounds), 0)
label.numberOfLines = 0
label.lineBreakMode = .ByWordWrapping
label.text = "This is a really\nlong string"
label.setNeedsLayout()
label.sizeToFit()
label.frame = CGRectMake(0, 0, CGRectGetWidth(label.bounds), CGRectGetHeight(label.bounds))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
And, as you can see here, it doesn't work as intended:
Don't use a frame, use autolayout. Add a top, leading, and trailing constraint to the label (I would suggest doing this in the storyboard). As long as you have lines equal to 0 (which you do), the height will adjust automatically. If you want to add the constraints in code, your viewDidLoad would look something like this:
override func viewDidLoad() {
super.viewDidLoad()
label.text = "This is a really\nlong string"
label.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(label)
let views = ["label": label]
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[label]-|", options: nil, metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[label]", options: nil, metrics: nil, views: views))
}

UIScrollView cannot display image either in Portrait or Landscape mode

I have created a VC with orientation in Landscape in storyboard
I have added an UIIScrollView in it , say, make it: (w)1000, 500 (h) in the VC.
What I wanted to do:
1) Scrolling the image (with high resolution like 1334 x 750) inside ScrollView
2) view the image in ScrollView in landscape mode
To make ScrollView to display the image, I have to do it in `viewDidAppear`
but here the Problems:
1) The Width and height of the `ScrollView` is gone
2) label on top gone.
3) The `ScrollView` Size become small something like 200 x 150 and start from the Top corner like (0,0)
What I need to do to make `scrollview` size like before 1000 x 500?
--- Update --
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var myUIScrollView: UIScrollView!
var imgView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
//-- force to landscape mode:
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
self.myUIScrollView.maximumZoomScale = 10.0
self.myUIScrollView.minimumZoomScale = 1.0
self.myUIScrollView.delegate = self
imgView = UIImageView(image: UIImage(named: "MyPhoto.png"))
}
override func viewDidAppear(animated: Bool) {
self.myUIScrollView.contentSize = imgView.bounds.size
self.myUIScrollView.addSubview(imgView)
view.addSubview(myUIScollView)
}
override func shouldAutorotate() -> Bool {
return true
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imgView
}
Try this:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
var image: UIImage!{
get{
return myImageView.image!
}set{
myImageView.image = newValue
myImageView.sizeToFit()
myScrollView.contentSize = myImageView.frame.size
}
}
var myImageView = UIImageView()
#IBOutlet weak var myScrollView: UIScrollView!{
didSet{
myScrollView.delegate = self
myScrollView.minimumZoomScale = 10.0
myScrollView.maximumZoomScale = 1.0
myScrollView.addSubview(myImageView)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
image = UIImage(named: "one")
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return myImageView
}
}

Resources