Swift 2 - change UIView background colour from another UIViewControl - ios

I am trying to change the colour of a UIView in View Controller when a button is pressed in Collection View Controller.
In my UIViewController I have a function that changes the color when this function is called from collection view controller the function prints out but the colour is not changed.
View Controller
static let sharedInstance = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("settingPageId") as! SettingsViewController
#IBOutlet weak var TopView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let colorsViewController = storyboard?.instantiateViewControllerWithIdentifier("colorsViewCollection")
self.addChildViewController(colorsViewController!)
colorCollectionView.addSubview((colorsViewController!.view)!)
}
func colorHasBeenSelected(){
TopView.backgroundColor = UIColor.blackColor() // color is not changed if called from collection view
print("colorHasBeenSelected") // it prints ok
}
Collection View Controller
let settingPage = SettingsViewController.sharedInstance
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
_ = settingPage.view // without it TopView returns nil
}
#IBAction func colorAction(sender: UIButton) {
settingPage.colorHasBeenSelected()
}
How can I make the UIView inside UIViewController change the background colour from the UICollectionView?

Related

subview not clickable in UIViewController

I'm trying to embed a custom view in UIViewController. But when displayed, it's not clickable since it's out of the UIView frame.
viewDidLoad:
#IBOutlet var theVC_InVC_Test: UIView!
#IBOutlet var TableView: UITableView!
override func viewDidLoad() {
TableView.delegate = self
TableView.dataSource = self
func embed(_ viewController:UIViewController, inView view:UIView){
viewController.willMove(toParent: self)
viewController.view.frame = view.bounds
view.addSubview(viewController.view)
self.addChild(viewController)
viewController.didMove(toParent: self)
}
embed(sidemenutest1(), inView: theVC_InVC_Test)
}
sidemenutest1 UIViewController:
func popItOver(){
let PopOverVC = UIStoryboard(name:"Main",bundle: nil).instantiateViewController(withIdentifier: "CoinsPopUp") as! CoinsPopUpViewController
self.addChild(PopOverVC)
PopOverVC.view.frame = UIScreen.main.bounds
self.view.addSubview(PopOverVC.view)
PopOverVC.didMove(toParent: self)
}
#IBAction func storeAction(_ sender: Any) {
popItOver()
}
It's displayed fine, but it's not clickable... When I tried to click the subview buttons, the TableView is clicked and not the subview.
You shouldn't add the popover menu as a container view controller. It should be presented from the controller as a modal view controller instead and set its background view color to be the translucent gray color.

Add a view controller as a subview in another view controller

I have already read this LINK , but not working for me. I want to show a viewController as a subview in another viewController.
Here is my code -
import UIKit
import CarbonKit
class ViewController: UIViewController, CarbonTabSwipeNavigationDelegate {
#IBOutlet weak var containerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let items = ["All", "WOMEN", "MEN", "KIDS", "HOME", "CITY"]
let carbonTabSwipeNavigation = CarbonTabSwipeNavigation(items: items, delegate: self)
carbonTabSwipeNavigation.insert(intoRootViewController: self)
}
func carbonTabSwipeNavigation(_ carbonTabSwipeNavigation: CarbonTabSwipeNavigation, viewControllerAt index: UInt) -> UIViewController {
// let screen = self.storyboard?.instantiateViewController(withIdentifier: "demo") as! demo
// showSubViewContrller(subViewController: vc)
// return screen
let storyBoard = getStoryBoardByIndentifier(identifier: "All")
let vc = storyBoard.instantiateViewController(withIdentifier: "AllViewController") as! AllViewController
showSubViewContrller(subViewController: vc)
return vc
}
//Subview Controller
func showSubViewContrller(subViewController:UIViewController) {
self.addChildViewController(subViewController)
subViewController.view.frame = containerView.frame
self.containerView.addSubview(subViewController.view)
subViewController.didMove(toParentViewController: self)
}
func getStoryBoardByIndentifier(identifier:String)->UIStoryboard {
return UIStoryboard.init(name: identifier, bundle: nil)
}
}
I have a NavigationBar and a tapBar. Would like to show the viewController inside the view in a container.
But when the view loads it's coverUp/hide the tabBar.
How to solve this and show the viewController in my specified container.
Project Link - GitHub
Somehow i am able to fix your issue with below changes:
Replace this method carbonTabSwipeNavigation.insert(intoRootViewController: self) with carbonTabSwipeNavigation.insert(intoRootViewController: self, andTargetView: containerView) in viewDidLoad
Note : Give UITaBar bottom constraint to SuperView not SafeArea:
Add below code in ViewController:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tabbar.invalidateIntrinsicContentSize()
}
After doing this when you run you will UITabBar:

I am trying to using a custom delegate in swift but when I want to call its methods, it did not get called

I have been searching for how the delegate works and I tried to do it in my project. Unfortunately, the delegate method I implement does not get called ever. I am trying to do a slide-out navigation panel. so what I did is that I put two uicontainerviews, one is for slide-out navigation panel and the other for main view controller
enter image description here
The code is that
For main view controller
protocol MainViewControllerDelegate {
func toggleSideMenu()
}
class MainViewController: UIViewController {
var delegate: MainViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Slide Action
#IBAction func slideMenuTapped(_ sender: UIBarButtonItem){
delegate?.toggleSideMenu()
print("Slide Menu has been tapped")
}
}
For container view controller
class ContainerVC: UIViewController {
#IBOutlet weak var SideMenuConstraint: NSLayoutConstraint!
#IBOutlet weak var slideMenuContainer: UIView!
#IBOutlet weak var mainViewContainer: UIView!
var mainViewController: MainViewController?
var isSideMenuOpened = false
override func viewDidLoad() {
super.viewDidLoad()
mainViewController = UIStoryboard.mainViewController()
mainViewController?.delegate = self
}
}
extension ContainerVC: MainViewControllerDelegate{
func toggleSideMenu() {
print("It works")
if isSideMenuOpened{
isSideMenuOpened = false
SideMenuConstraint.constant = -260
mainViewContainer.layer.shadowOpacity = 0
} else {
isSideMenuOpened = true
SideMenuConstraint.constant = 0
mainViewContainer.layer.shadowOpacity = 0.59
}
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
}
extension UIStoryboard{
static func mainStoryboard() -> UIStoryboard { return UIStoryboard(name: "Main", bundle: Bundle.main) }
static func mainViewController() -> MainViewController? {
return mainStoryboard().instantiateViewController(withIdentifier: "MainViewController") as? MainViewController
}
}
Please let know what's wrong
I think the reason is that you embed your main view controller in navigation controller :
let navigationController = self.childViewControllers.last as! UINavigationController
let mainViewController = navigationController.topViewController as! MainViewController
mainViewController?.delegate = self
Here is where you got wrong:
mainViewController = UIStoryboard.mainViewController()
mainViewController?.delegate = self
this mainViewController is not the same as the child of the container view controller, so setting its delegate doesn't really do anything.
You need to first get the VC that is the child of the container view controller:
mainViewController = self.childViewControllers.last as! MainViewController
mainViewController.delegate = self

How to add action to UIBarButtonItem which is created by storyboard in swift?

Create a UIBarButtonItem which name is nextVc on my navigationBar, and set its action by nextVc.action = #selector(self.gotoVC4), but it does not work.
my code is below:
class ViewController3: UIViewController {
#IBOutlet weak var nextVc: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
nextVc.action = #selector(self.gotoVC4)
}
func gotoVC4() -> Void {
print("go to vc4")
let vc4 = ViewController4()
self.navigationController!.pushViewController(vc4, animated: true)
}
}
and the image of storyboard is here:
Since you have a storyboard, simply ctrl-drag from the bar button to the "View Controller 4" scene to create a segue. No code needed.
You can omit self in selector expression
Method should be dynamic or #objc
override func viewDidLoad() {
super.viewDidLoad()
nextVc.action = #selector(gotoVC4)
}
dynamic func gotoVC4() -> Void {
print("go to vc4")
let vc4 = ViewController4()
self.navigationController!.pushViewController(vc4, animated: true)
}

Swift Delegate function not being executed

I have a UIPageViewcontroller containing three ViewControllers. One Viewcontroller is my ProfileViewcontroller. I have a button in my ProfileViewController, which should tell the UIPageViewCongtroller when pressed, to switch to the next Viewcontroller.
It's my first time implementing a delegate, but I just can't figure out why its not working.
UIPageViewController class:
class PageViewController: UIPageViewController, ProfileViewControllerDelegate {
private(set) lazy var orderedViewControllers: [UIViewController] = {
// The view controllers will be shown in this order
return [self.newColoredViewController("Search"),
self.newColoredViewController("Menu"),
self.newColoredViewController("Profile"),
self.newColoredViewController("Offer")]
}()
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if orderedViewControllers.count >= 2 {
scrollToViewController(orderedViewControllers[1])
}
}
// MARK: ProfileViewControllerDelegate
func profileViewControllerDidTouchOffer(viewController:ProfileViewController, sender: AnyObject) {
scrollToNextViewController()
print("I'm pressing the offer Button")
}
ProfileViewController class:
protocol ProfileViewControllerDelegate : class {
func profileViewControllerDidTouchOffer(controller: ProfileViewController, sender: AnyObject)
}
class ProfileViewController: UIViewController {
weak var delegate: ProfileViewControllerDelegate?
#IBOutlet var profileImageView: SpringImageView!
#IBOutlet var offerButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func offerButtonTouchUpInside(sender: AnyObject) {
delegate?.profileViewControllerDidTouchOffer(self, sender: sender)
}
Answer
I updated the PageViewController class by changing the way I add the ViewControllers in orderderedViewControllers:
private(set) lazy var orderedViewControllers: [UIViewController] = {
// The view controllers will be shown in this order
let profileVC = UIStoryboard(name: "Main", bundle: nil) .instantiateViewControllerWithIdentifier("ProfileViewController") as! ProfileViewController
profileVC.delegate = self
return [self.newColoredViewController("Search"),
self.newColoredViewController("Menu"),
profileVC,
self.newColoredViewController("Offer")]
}()
Looks like you're using the InterfaceBuilder so I'm not sure how it's done there (probably in prepareForSegue), but a typical pattern is something like this:
let vc = ProfileViewController()
vc.delegate = self // Or whatever you want to act as the delegate
// Now show the view controller.
The key is that before using the view controller, you make sure it's delegate property is set to the thing that is the delegate and conforms to the protocol. Typically the calling controller would be the delegate.
EDIT: If you're using the UIPageViewController, then you should add the delegate to the viewController before passing it to setViewControllers https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPageViewControllerClassReferenceClassRef/#//apple_ref/occ/instm/UIPageViewController/setViewControllers:direction:animated:completion:

Resources