Swift: Scroll view with image view isn't enabled? - swift

So I created a scroll view and put an image view in it. I initialized the scroll view as a variable and wrote the following code in my ViewController and yet, the image won't scroll.
What's wrong?
Later on I'm also going to need to put several buttons into this scroll view so if I'm missing something here, it'd be great if you could address it for buttons as well.
My code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
ScrollView.scrollEnabled = true
}
#IBOutlet weak var ScrollView: UIScrollView!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Try explicitly setting the content size like so:
self.scrollView.contentSize = CGSize(width:somethingBigger, height: somethingBigger);
To answer your follow-up question...Make height of the scrollView equal to that of the screen. Then it won't scroll vertically. Programmatic stuff overwrites storyboard stuff.

Related

how to set background colour of a container view

i have dragged a container view from storyboard and set it black in background colour. but it didn't change the background colour.
class ViewController: UIViewController {
#IBOutlet weak var container: UIView!
override func viewDidLoad() {
super.viewDidLoad()
container.layer.backgroundColor = UIColor.blackColor().CGColor
// 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.
}
}
How did you set the background color?
A container view is actually just a normal view, that is linked to a viewController. This means you can set the background the same way as you would for any other NSView or UIView. This is all the code I needed to add to my NSViewController class (not the ViewController inside the container, just the ViewController for the window).
#IBOutlet weak var containerView: NSView!
override func viewDidLoad() {
//other code in your viewDidLoad
containerView.wantsLayer = true
}
override func awakeFromNib() {
super.awakeFromNib()
containerView.layer?.backgroundColor = NSColor.black.cgColor
}
make sure to connect the IBOutlet if you have not already.
If you set the layers background color in viewDidLoad, the layer may not exist yet, (I don't know why). Accessing the layer in awakeFromNib has always worked for me, while accessing it in the viewDidLoad can be unreliable.
If you are working on IOS, most of this is not applicable, and this should be all you need
#IBOutlet weak var containerView: UIView!
override func viewDidLoad() {
containerView.layer?.backgroundColor = UIColor.black.cgColor
}
I work less on IOS, so I have not ran into any issues with that, but that could be from lack of attempts. On OSX setting the background color in viewDidLoad will work about 50% of the time so there might still be an issue that I have not ran into.
If neither works, try unwrapping the layer rather than leaving it an optional (replacing the ? with a !) this will at least crash your program and probably tell you that layer is nil, if this is the case you should be figuring out why the layer is nil.
Also if the ViewController connected to the container view is a custom class, you don't have to bother with the IBOutlets, just call the view "view" in that custom class.
Sorry this got a bit long, but hope this helped

viewWillAppear method doesn't work

import UIKit
class ViewController: UIViewController {
#IBOutlet weak var family_name: UITextField!
#IBOutlet weak var given_name: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
family_name.center.x -= view.bounds.width
given_name.center.x -= view.bounds.width
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
viewWillAppear has no effect. When I run my app both text fields shouldn't be visible, but they are. I attached a photo with constraints; I think this can be the problem!
You are using autolayout, so frame change will not apply. your constraints will overwrite frame values after viewWillAppear:
Create IBOutlet for either right constraint or width constraint of your textFields.
Check below sample image to create IBOutlet of constraint.
In above image I have create outlet of height constraint.
To send textField outside of the view, suppose you have created right constraint.
//suppose initial value of right constraint is 20
constraintTextView1Right.constant = 20 + self.view.bounds.width;
self.view.layoutIfNeeded();//forcefully apply constraint with new values
After this, at some point in button click or in other event or after some delay, you can change value of constraintTextView1Right to 20,
constraintTextView1Right.constant = 20
self.view.layoutIfNeeded();//forcefully apply constraint with new values
your textFiled will come in the screen.
To animate the same you can write below code.
constraintTextView1Right.constant = 20
UIView.animateWithDuration(0.3) { () -> Void in
self.view.layoutIfNeeded();//forcefully apply constraint with new values
}

Swift - Cropping images *outside* of allowsEditing

I have a very very simple project set up that allows you to click a "browse photo" button. The user then selects a photo from their photo gallery, and it's displayed on a programmatically created UIImageView.
Works like a charm. However - I am missing key functionality that is required.
I need the user to be able to scale the image (via pinching and dragging) after it is displayed within the UIImageView. allowsEditing = true, lets the user crop before. I need similar functionality, however, allowing them to edit once it's on the main UI.
Help is appreciated. Please and thank you!!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var imageViewLayer: CALayer{
return imageView.layer
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imageViewLayer.contents = UIImage(named: "ss3.jpg")?.CGImage
imageViewLayer.contentsGravity = kCAGravityResizeAspect
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func newGesture(sender: AnyObject) {
imageViewLayer.transform = CATransform3DMakeScale(sender.scale, sender.scale, 1)
}
}
I did something similar a while back. I added the image to UIImageView's layer property, added gesture recognizer to the view and implemented the gesture call backs modifying the layer property and not the view. Adding the image to the UIImageView's layer did the trick. As a side note, I would like to add that every UIView is supported by CALayer class. It has a lot of methods and properties which help to dynamically change the view, which in your case will be done by gestures.
As an alternative, you can also use CALayer's hitTest method instead of implementing the call backs for gesture recognizers.
EDIT- Sample Code
You could do some thing like this:
#IBOutlet weak var imageView: UIImageView!
var imageViewLayer: CALayer{
return imageView.layer
}
In the viewDidLoad, set up the image
imageViewLayer.contents = UIImage(named: "CoreDataDemoApp")?.CGImage
imageViewLayer.contentsGravity = kCAGravityResizeAspect
Add pinch gesture to the imageview in storyboard (or programmatically) and in it's call back you could do something like this:
#IBAction func pinchGestureRecognized(sender: AnyObject) {
imageViewLayer.transform = CATransform3DMakeScale(sender.scale, sender.scale, 1)
}
Again this is just to give you an idea of how it could work and it is not the complete code. Hope this helps!
This is another way of doing it:
Stackoverflow link to related question

How can I change the view in a container view (embedded view controller)?

So I have been trying to do this for a a while, that I need to to do is be able to change the image view that a container view embeds. Is this possible?
I wasn't sure if it was, so I thought that maybe I could just make an embedded view for all of the different views and have them all on top of each other - then just bring the one that the user has chosen to the view to the top.
I'm pretty sure the second way would work, but it would probably slow down the app and isn't very tidy.
I would prefer to use the first way and just be able to choose which view controller the view controller embeds.
I know that stack overflow likes to see that the OP has made an attempt at solving the problem, but I am asking more here if it is possible to do the first way - if it is, how would I go about doing it. If it isn't would my second option be feasible?
Thanks
One way is as shown below.
import UIKit
class ViewController: UIViewController {
var imgNumber = 0
var images = ["image0","image1","image2"]
#IBAction func btn(sender: UIButton) {
imgNumber += 1
if (imgNumber > 2) {
imgNumber = 0
}
imageToBeDisplayed.image = UIImage(named: images[imgNumber])
}
#IBOutlet weak var imageToBeDisplayed: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageToBeDisplayed.image = UIImage(named: images[0])
// 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.
}
}

Setting a Border for TextView (Xcode 6.1)

I've tried finding the answer to this and every time it's assuming I know way too much. I'm a total beginner. I just created a new, blank application. I dragged the TextView to the storyboard. What do I do next to give it a border?
There is no code other than the default, autogenerated code at this point.
Here are the steps:
If you let Xcode create a project, go to the ViewController.swift file. Here you can create an outlet.
#IBOutlet var text : UITextField?
Now you can connect the text outlet to the textfield in the storyboard. You can do this by choosing the assistant editor. Than control drag a line from the outlet in the code to the textfield.
After the textfield is connected, you can add code to make a border in the viewDidLoad function.
class ViewController: UIViewController {
#IBOutlet var text : UITextField?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
text!.layer.borderWidth = 1
text!.layer.borderColor = UIColor.redColor().CGColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In Swift 3 and Xcode 10,
tested and working in (swift 5 and code 12)
first, create an outlet of your text view
And In your viewdidload put these two lines
class ViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.textView.layer.borderColor = UIColor.lightGray.cgColor
self.textView.layer.borderWidth = 1
}
}