button load from xib via loadNibNamed() never called - ios

Another problem arrived me. I have a view covering my hole screen. In it a webView for showing a youTube video and a button for closing. The view is load via loadNibNamed() and no matter what I'm doing, my IBAction never called by pressing that button.
I tried to make an IBAction via storyboard, also via addTarget to a buttonoutlet. Both never called. My button is reachable when I click it, it show the default touchanimation. Also printing the button outlet in viewDidLoad() says <UIButton: 0x17d25430; frame = (15 8; 39 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x17d25ae0>> so it is not nil.
My Layout looks like the following.
MainScreen: UIViewController, UITableViewDelegate, UITableViewDataSource, UIWebViewDelegate{}
In one of mainScreens tableView is a customCell named videoViewCell implemented with:
let cell = NSBundle.mainBundle().loadNibNamed("VideoViewCell", owner: self, options: nil)!.first as! VideoViewCell
videoViewCell: UITableViewCell , UITableViewDelegate, UITableViewDataSource {} has:
weak var delegate: ActivityDetailVideoCellDelegate?
...
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
delegate?.selectedCellAtIndex(indexPath.row)
}
...
protocol ActivityDetailVideoCellDelegate: class {
func selectedCellAtIndex(index: Int)
}
My mainScreen class has:
extension MainScreen: ActivityDetailVideoCellDelegate {
func selectedCellAtIndex(index: Int) {
let youtubeLink: String = "http://www.youtube.com/embed/\(selectedVideo)"
let youtubePopup = YouTubePopUpController()
youtubePopup.view.frame = self.view.bounds
youtubePopup.view.alpha = 0
youtubePopup.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
let code: String = "<iframe width=\(youtubePopup.webView.bounds.width) height=\(youtubePopup.webView.bounds.height) src=\(youtubeLink) frameborder=0 allowfullscreen></iframe> <style>body { margin: 0; padding: 0; }</style>"
youtubePopup.webView.loadHTMLString(code, baseURL: nil)
self.view.addSubview(youtubePopup.view)
UIView.animateWithDuration(0.25, animations: { () -> Void in
youtubePopup.view.alpha = 1
youtubePopup.view.transform = CGAffineTransformMakeScale(1, 1)
})
}
}
YouTubePopUpController: UIViewController:
#IBOutlet weak var backgroundView: UIView!
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var closeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
print(closeButton)
closeButton.addTarget(self, action: #selector(self.closeButtonClicked(_:)), forControlEvents: .TouchUpInside)
}
#IBAction func closeButtonClicked(sender: AnyObject) {
print("close clicked")
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
self.view.alpha = 0
}) { (finished) -> Void in
self.view.removeFromSuperview()
}
}
my xib:

Finally solved my Problem by writing the #IBAction func closeButtonClicked(sender: AnyObject) {} inside my MainScreenViewController an adding Target inside func selectedCellAtIndex(index: Int) {} to call my youtubePopUp inside closeButtonClicked I made it global:
#IBAction func closeButtonClicked(sender: AnyObject) {
print("close clicked")
youtubePopup!.webView.loadHTMLString("about:blank", baseURL: nil)
youtubePopup!.webView.mediaPlaybackRequiresUserAction = false
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.youtubePopup!.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
self.youtubePopup!.view.alpha = 0
}) { (finished) -> Void in
self.youtubePopup!.view.removeFromSuperview()
}
}

Related

How can I check the alpha of container views with the button in the bottom view of the container view-Swift 4 -IOS

Main.StoryBoard in this way
class ForgotPasswordContainerControl: UIViewController {
#IBOutlet var screenStep1: UIView?
#IBOutlet var screenStep2: UIView?
#IBOutlet var screenStep3: UIView?
override func viewDidLoad() {
super.viewDidLoad()
self.screenStep1?.alpha = 1.0
self.screenStep2?.alpha = 0.0
self.screenStep3?.alpha = 0.0
}
#IBAction func step1ButtonClick(_ sender: UIButton) {
UIView.animate(withDuration: 0.5, animations: {
self.screenStep1?.alpha = 0.0
self.screenStep2?.alpha = 1.0
self.screenStep3?.alpha = 0.0
print("clicked button1 ")
})
print("clicked button2 ")
}
}
My code is working in viewdDidLoad, clicking the button prints is working
but Alpha does not work, how can i do?

How to update the layout (position) of a popover when its source view changes theirs in Swift?

I want to update the layout of a popover, I've already tried using the setNeedsLayout() and layoutIfNeeded() methods but couldn't find a solution.
I have a simple screen with 4 buttons that call a popover, within the popover there are 2 extra buttons:
Button -> hides button3, and moves button1 and button2 to the left.
reposition -> changes the sourceview of the popover from the button1/2/3/4 (sender) to button4.
Picture of the layout
The problem I have is that I'm not able to update/refresh the screen, and the popover keeps pointing to the former source view position.
Picture of the popover
Somehow I need a method that updates my view and which is stronger than layoutIfNeeded() because if the screen is changed from portrait/landscape the popover changes automatically. Here I changed portrait/landscape/portrait
GitHub of the project. GitHub
The code used is the following:
class ViewController: UIViewController, ButtonDidDisappearDelegate {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
#IBOutlet weak var button4: UIButton!
#IBOutlet weak var constrain2: NSLayoutConstraint!
var popVC: PopVC?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttonPopover(_ sender: UIButton) {
configureAndPresentPopover(from: sender)
}
func buttonDisappear() {
self.constrain2.constant = 100
self.button3.isHidden = !self.button3.isHidden
if !self.button3.isHidden {
self.constrain2.constant = 10
}
}
func repositionPopover() {
DispatchQueue.main.async {
if let popVC = self.popVC {
self.self.popoverPresentationController(popVC.popoverPresentationController!, willRepositionPopoverTo: self.button4.bounds, in: self.button4)
}
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
}
}
}
extension ViewController: UIPopoverPresentationControllerDelegate {
func configureAndPresentPopover(from sender: UIButton) {
popVC = storyboard?.instantiateViewController(withIdentifier: "popVC") as? PopVC
guard let popVC = popVC else {
return
}
popVC.popOverDelegate = self
popVC.modalPresentationStyle = .popover
let popOverVC = popVC.popoverPresentationController
popOverVC?.delegate = self
popOverVC?.sourceView = sender
popOverVC?.sourceRect = sender.bounds
popVC.preferredContentSize = CGSize(width: 300, height: 60)
popOverVC?.permittedArrowDirections = .down
self.present(popVC, animated: true)
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController,
willRepositionPopoverTo rect: CGRect,
in view: UIView) {
popoverPresentationController.sourceView = view
popoverPresentationController.sourceRect = rect
}
}
and the popover controller:
protocol ButtonDidDisappearDelegate: class {
func configureAndPresentPopover(from sender: UIButton)
func buttonDisappear()
func repositionPopover()
}
class PopVC: UIViewController {
weak var popOverDelegate: ButtonDidDisappearDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var popoverButton: UIButton!
#IBAction func popoverAction(_ sender: Any) {
popOverDelegate?.buttonDisappear()
DispatchQueue.main.async {
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
}
}
#IBAction func reposition(_ sender: Any) {
popOverDelegate?.repositionPopover()
}
}
You need to specify the new position of the arrow and ask for the layout of the presentation controller's view, not only the presented view.
Try :
func repositionPopover() {
let popOverController = presentedViewController?.presentationController as? UIPopoverPresentationController
popOverController?.sourceView = button4
popOverController?.containerView?.setNeedsLayout()
popOverController?.containerView?.layoutIfNeeded()
}
You can try setting the sourceview and sourcerect once again. call this function when the sourcview bounds are changed.

Change the value of another class (Extension) with argument

A function whose argument is used for Extension of another class is described.
I want to change the value of the UIView property (alpha) that exists in that function "at the button tap in another class".
However, this function can be changed at ViewDidLoad time.
How can I change the value when tapping buttons?
If possible please write the code.
ViewController Class
class ViewController: UIViewController {
#IBOutlet weak var vHome: UICollectionView!
#IBOutlet weak var vSearch: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
selectRd(rd: 3) //This time can change calue of alpha.
}
}
extension ViewController {
func selectRd(rd reader:Int){
var animateView:UIView!
let animateVHome = vHome
let animateVSearch = vSearch
UIView.animate(withDuration: 0.3, delay: 0.0, animations: {
animateVHome.alpha = 0.0
animateVSearch.alpha = 0.0
}, completion: nil)
switch reader {
case 2:
animateView = animateVHome
case 3:
animateView = animateVSearch
default:
break
}
UIView.animate(withDuration: 0.3, delay: 0.3, animations: {
animateView.alpha = 1.0
}, completion: nil)
}
}
Another Class
class Another{
#objc func buttonTapped(sender : HeaderButton) {
let vC = ViewController
vC.selectRd(rd: 2) //This time can not!!
}
}
Please comment if you can not understand the question.
The problem is that you can't access a function of a class if its currently active , as this will result in a crash , so Add a var in viewControler
class ViewController: UIViewController {
#IBOutlet weak var vHome: UICollectionView!
#IBOutlet weak var vSearch: UICollectionView!
var index:Int?
override func viewDidLoad() {
super.viewDidLoad()
selectRd(rd: self.index) //This time can change calue of alpha.
}
}
..
class Another{
#objc func buttonTapped(sender : HeaderButton) {
let vC = ViewController
vC.index = 2 //This time can not!!
}
}

Unable to Convert String To Date App crashes and showing outlet is nil

I am loading a views from nib and i am successfully loaded but first one is loaded perfect but in second view getting nil outlets. below is my code.
Set a global variable to loadview by default is is 0 and it is increase when i press next button.
User is struct here :
struct User {
static var quizIndexNo = 0
}
This method is in my ViewController
let moptViewInstance = MOPT()
let rmkViewInstance = RMK()
getting view name from this array:
let viewName = ["MOPT","RMK"]
func loadQuizView(){
if viewName[User.quizIndexNo] == "MOPT" {
for views in vwOptionView.subviews {
views.removeFromSuperview()
}
moptViewInstance.prepareScreenWithView(navigationController: UINavigationController(), viewSize: self.vwOptionView, viewController: self)
} else if viewName[User.quizIndexNo] == "RMK" {
for views in vwOptionView.subviews {
views.removeFromSuperview()
}
rmkViewInstance.prepareScreenWithView(navigationController: UINavigationController(), viewSize: self.vwOptionView, viewController: self)
}
}
// NIB View Classes
class MOPT: UIView {
#IBOutlet weak var btnPrevious: UIButton!
#IBOutlet weak var btnNext: UIButton!
var nibView: UIView!
var instanceOfQuizController : QuizCointroller!
func prepareScreenWithView(navigationController: UINavigationController, viewSize: UIView, viewController: UIViewController) {
nibView = Bundle.main.loadNibNamed("MOPT", owner: self, options: nil)?[0] as! UIView
nibView.tag = 200
var tempRect = nibView.frame
print(tempRect)
if User.quizIndexNo == 0 {
btnPrevious.isHidden = true
}
if User.quizIndexNo == 0 {
btnNext.setTitle("Test", for: .normal)
}
print("Index No is: \(User.quizIndexNo) and \(Sequence.totalQuizQuestionCout)")
if User.quizIndexNo == Sequence.totalQuizQuestionCout - 1 {
btnNext.setTitle("Submit", for: .normal)
}
instanceOfQuizController = viewController as! QuizCointroller
tempRect = CGRect(x: 0, y: 0, width: viewSize.bounds.width, height: viewSize.bounds.height)
viewSize.addSubview(self.nibView)
self.nibView.frame = tempRect
}
#IBAction func btnPrev(_ sender: UIButton) {
User.quizIndexNo -= 1
Sequence.instanceOfQuizControllerTest.previousButtonPressed()
}
// Next button will reload next view
#IBAction func btnNext(_ sender: UIButton) {
User.quizIndexNo += 1
// here sequence is global variable of type ViewController
Sequence.instanceOfQuizControllerTest.nextButtonPressed()
}
}
Second NibView Class
class RMK: UIView {
#IBOutlet weak var btnPrevious: UIButton!
#IBOutlet weak var btnNext: UIButton!
var nibView: UIView!
var instanceOfQuizControllerTest : QuizCointroller!
func prepareScreenWithView(navigationController: UINavigationController, viewSize: UIView, viewController: UIViewController) {
nibView = Bundle.main.loadNibNamed("RMK", owner: self, options: nil)?[0] as! UIView
nibView.tag = 200
var tempRect = nibView.frame
print(tempRect)
if User.quizIndexNo == 1 {
btnPrevious.isHidden = true //app is crashing here when i am trying to set title Button is showing nil
}
if User.quizIndexNo == 1 {
btnNext.setTitle("Submit", for: .normal)
}
instanceOfQuizControllerTest = viewController as! QuizCointroller
print("Quiz ViewController instatnce \(instanceOfQuizControllerTest)")
tempRect = CGRect(x: 0, y: 0, width: viewSize.bounds.width, height: viewSize.bounds.height)
viewSize.addSubview(self.nibView)
self.nibView.frame = tempRect
}
#IBAction func btnPrev(_ sender: UIButton) {
User.quizIndexNo -= 1
Sequence.instanceOfQuizControllerTest.previousButtonPressed()
}
#IBAction func btnNext(_ sender: UIButton) {
print(instanceOfQuizControllerTest)
User.quizIndexNo += 1
Sequence.instanceOfQuizControllerTest.nextButtonPressed()
}
}

Weird Button Animation

It's my first try on IOS animation, so if I'm worry from the very beginning, just tell me the right direction.
All I want: when I click ButtonOne, Label disappears slowly.
The code as below:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var labelHeight: NSLayoutConstraint!
private var isHidden: Bool = false
#IBAction func clickButtonOne(sender: UIButton) {
isHidden = !isHidden
if isHidden {
labelHeight.constant = 0
} else {
labelHeight.constant = 60
}
UIView.animateWithDuration(1.0, animations: {
() -> Void in
self.view.layoutIfNeeded()
}, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Before I click ButtonOne:
After I click ButtonOne(label shrinks from bottom to top):
The UILabel is disappearing, but it's content is still visible.
You need to set the clipsToBounds property of the UILabel to true.
label.clipsToBounds = true
You can set the same property in the interface builder by checking the Clip Subviews property in the attributes inspector.
I think you should also animate UIView.alpha property:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBOutlet weak var labelHeight: NSLayoutConstraint!
private var isHidden: Bool = false
#IBAction func clickButtonOne(sender: UIButton) {
isHidden = !isHidden
var alpha: CGFloat = 1
if isHidden {
alpha = 0
labelHeight.constant = 0
} else {
labelHeight.constant = 60
}
UIView.animateWithDuration(1.0, animations: {
() -> Void in
self.button.alpha = alpha
self.view.layoutIfNeeded()
}, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}

Resources