How to add UIViewController into UIScrollView in swift? - ios

I want to add UIViewController into UIScrollView.
I searching and tried, but I can't find solution.
The most understandable way is this.
Here is my code.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.contentSize.width = self.view.frame.width * 2
let test = self.storyboard?.instantiateViewController(withIdentifier: "Test") as! TestViewController
self.addChild(test)
self.scrollView.addSubview(test.view)
test.willMove(toParent: self)
test.view.frame.origin = CGPoint.zero
}
}
But, I this way is error like this.
How to add UIViewController into UIScrollView??
Please Help me.

In your storyboard, just drag and drop a containerView, it will make a UIViewController
in your scrollView as you want

Related

Hide an image set in storyboard for a particular condition in ios

I have an image which I have put i storyboard but I need to hide it for a particular user. I am not sure how to do it in the code. I ll share what I have done:
in controller.h I write:
#property (weak, nonatomic) IBOutlet UIImageView *downArrowImage;
In controller.m
I put my if condition and inside it , I do this:
[self.downArrowImage setHidden:NO];
This I do in intializeView but iut doesnt work, any suggestions?
My image name is DownArrowImage. I am not sure how the linking between image and the variable downArrowImage takes place.
User this code.
imageVIew.isHidden = true
or
height.constant = 0
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageVIew: UIImageView!
#IBOutlet weak var height: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
//height.constant = 0
imageVIew.isHidden = true
}
}
Second screenshot.

Make UIImageView accessible from all viewControllers

My question is, how can I make it so redDot and wCircle can be accessed from the Second viewController so they can become hidden or not hidden. They are not connected directly, but you can get to them with different viewControllers.
First viewController
class SecondViewController: UIViewController
{
#IBOutlet weak var redDot: UIImageView!
#IBOutlet weak var wCircle: UIImageView!
}
Second viewController
class ProgressViewController: UIViewController {
#IBOutlet weak var rDot: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
rDot.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(rdotimageTapped(tapGestureRecognizer:)))
rDot.addGestureRecognizer(tapGestureRecognizer)
view.bringSubview(toFront: rDot)
}
func rdotimageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
wcircle.isHidden = true
redDot.isHidden = false
view.layoutIfNeeded()
print("It worked")
}
Im not sure if this is a right way but what I would do is have a reference of UIImageView in my second VC and then set that to the imageView of my first VC.
So add these two in your "ProgressViewController"
var redDot: UIImageView?
var wCircle: UIImageView?
and then in your prepare for segue pass your current UIImageView.
let progressViewController = segue.destination as! ProgressViewController
progressViewController.redDot = self.redDot
progressViewController.redDot.wCircle = self.wCircle
You can achieve that by adding a new member to your second and third view controllers, this member is a closure:
var updateFirstViewControllerImageViews: (() -> Void)?
Then override prepare for segue method of your firstViewController, and set updateFirstViewControllerImageViews for each of your second and third view controller like this:
secondViewController.updateFirstViewControllerImageViews = {
// Update your image views here in the way you want!
}
Now, in your second and third view controllers you can use that closure wherever you want like this:
self.updateFirstViewControllerImageViews?()

Swift Call component from UIViewController in a UIView [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 6 years ago.
I'm having a problem, I have a UIButton in a UIViewController class and I want to enable that button after an animation that happens in a UIView class that is in another file.
class MainViewController: UIViewController {
#IBOutlet weak var nextButton: UIButton!
#IBAction func nextButtonPressed(sender: UIButton) {
nextButton.enable = false
}
}
When I try to call the nextButton from the viewController class after the animation is done I get this error:
EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP, subcode = 0x0)
I get the error on the line where I set the nextButton enable to true.
class CustomView: UIView {
var vc = MainViewController()
func animationEnded() {
vc.nextButton = true
}
}
I don't have a clue what I'm missing and I would appreciate some help. Thanks
You encounter an error because in your CustomView you create a new MainViewController, you're not using the one initialized from the storyboard. That new MainViewController doesn't have any of its properties initialized, so nextButton is nil, hence the crash when you try to access it.
What you want to do is notify your controller from the view that the animation has ended so that the controller can update the button (since the controller owns the button). The standard way to do this in Cocoa is to use the delegate pattern like so:
class MainViewController: UIViewController, CustomViewDelegate
{
#IBOutlet weak var nextButton: UIButton!
#IBOutlet weak var customView: CustomView!
#IBAction func nextButtonPressed(sender: UIButton) {
self.nextButton.enabled = false
}
override func awakeFromNib() {
super.awakeFromNib()
self.customView.delegate = self
}
func customViewAnimationDidEnd(customView: CustomView) {
self.nextButton.enabled = true
}
}
protocol CustomViewDelegate : class
{
func customViewAnimationDidEnd(customView: CustomView)
}
class CustomView: UIView
{
weak var delegate: CustomViewDelegate? = nil
func animationEnded() {
self.delegate?.customViewAnimationDidEnd(self)
}
}
In this implementation the controller is the view delegate and gets notified when interesting events happen in the view (like a particular animation ending).
Make a delegate in your UIView that tells when it should hapen
protocol CustomViewDelegate {
func pushThatButton()
}
in CustomView class put this:
weak var delegate: CustomViewDelegate?
then
func animationEnded() {
delegate.pushThatButton()
}
and in UIViewController
class MainViewController: UIViewController, CustomViewDelegate {
and implement delegate ofc
func pushThatButton()
nextButton.sendActionsForControlEvents(.TouchUpInside)
}
almost forget, do an outlet to your view in viewController and setup delegate! in viewDidLoad() or when you will find this best
customViewOutlet.delegate = self

ScrollView unable to display image which passed from another VC

I need to display the image pass in from the another ViewController
first,I have tested using only ImageView to display the image and it works as below:
Thanks. Your help is greatly appreciated.
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var TempImgView: UIImgeView!
var passInImg: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
TempImgView.image = passInImg!
}
When I use UIScrollView ( for scrolling the large passInImg) , below code not working
Probelm:
error : fatal error: unexpectedly found nil while unwrapping an
optional value
But I have tested the pass in image in the above code.
what need to be done with the scrollView?
Should be used in viewDidLoad?
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var myUIScrollView: UIScrollView!
var myImgView: UIImageView!
var passInImg: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
self.myUIScrollView.maximumZoomScale = 10.0
self.myUIScrollView.minimumZoomScale = 1.0
self.myUIScrollView.delegate = self
myImgView.image = passInImg!
self.myUIScrollView.addSubview(myImgView)
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return myImgView
}
First check if myUIScrollView is connected to an outlet in storyboard and always check before using an optional variable:
if let img = passInImg {
myImgView.image = img
}
The difference is the way you are declaring the UIImageView.
In the first case:
#IBOutlet weak var TempImgView: UIImageView!
TempImgView is an #IBOutlet and hence initialised whenever the storyboard view/xib is loaded.
But then when you are using the scrollview, you have declared the UIImageView as a class variable and not #IBOutlet.
var myImgView: UIImageView!
It has to initialised before you try to access it.
Try:
myImgView = UIImageView()
myImgView.image = passInImg!
Please initialize the myImgView with frame before set the image.
It return nil because the myImgView not initalize
myImgView = UIImageView(frame:CGRectMake(10, 50, 100, 300));
It works for me. Hope it will helps you.Thanks alot

Sidemenu using swift - reference taken https://github.com/evnaz/ENSwiftSideMenu

I have created common sidemenu for all main view controller using reference https://github.com/evnaz/ENSwiftSideMenu
Now the issue is i have created sidemenu view controller from storyboard instead of using code itself,it will not show anything on side menu.
Ideally it has to show the page which design from story board.
Actually only TableViewController work with this example. i need to work with UIViewController.
Anyone have idea about this ?
Check out the latest version, I added precisely that functionality a few weeks ago: you can now use a UIViewController, no need to use a UITableViewController.
But other than that, I can't tell without more information why it doesn't show up.
I'm using it in several apps and it works ok.
I've got a UINavigationController, which uses a subclass of ENSideMenuNavigationController, and a UIViewController for the menu itself.
This is it, basically:
class MainNavigationController: ENSideMenuNavigationController, ENSideMenuDelegate {
override func viewDidLoad() {
super.viewDidLoad()
var mainMenuViewController: MainMenuViewController = storyboard?.instantiateViewControllerWithIdentifier("MainMenuViewController") as! MainMenuViewController
mainMenuViewController.navController = self
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: mainMenuViewController, menuPosition:.Right)
//sideMenu?.delegate = self //optional
sideMenu?.menuWidth = 240.0 // optional, default is 160
sideMenu?.bouncingEnabled = false
sideMenu?.animationDuration = 0.2
// make navigation bar showing over side menu
view.bringSubviewToFront(navigationBar)
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
println("sideMenuWillOpen")
}
func sideMenuWillClose() {
println("sideMenuWillClose")
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
super.didRotateFromInterfaceOrientation( fromInterfaceOrientation )
sideMenu?.updateFrame()
}
}
Then I have the menu view itself, also in the Storyboard, which is a UIViewController. Here is a fragment:
class ERAMainMenuViewController: UIViewController {
weak var navController: ERAMainNavigationController?
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var exitButton: UIButton!
#IBOutlet weak var headImage: UIImageView!
let kInset:CGFloat = 64.0
override func viewDidLoad() {
super.viewDidLoad()
// Customize apperance of table view
tableView.contentInset = UIEdgeInsetsMake(kInset, 0, 0, 0) //
tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
tableView.backgroundColor = ERAssistantTheme.sideMenuItemBackgroundColor
tableView.scrollsToTop = false
// Preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = true
// tableView.selectRowAtIndexPath(NSIndexPath(forRow: selectedMenuItem, inSection: 0), animated: false, scrollPosition: .Middle)
}
}

Resources