Swift: How can I make UITextView in UITableViewCell firstresponder - ios

I have searched (so far unsuccessfully) for an (understandable) solution to this problem. My app uses UITableViews with cells that contain UITextViews. I want to be able to select the UITextView rather than the underlying cell. I understand that I need to make it the firstresponder but cannot find out how to do this. I am using Swift 2.
Update - my code
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
{
switch (getTipsInfo(viewName, sectionNumber: indexPath.section, tipOrder: indexPath.row).tipType) {
case "URL":
defaults.setObject(getTipsInfo(viewName, sectionNumber: indexPath.section, tipOrder: indexPath.row).tipLinkName, forKey: "URL")
myStack.push(getViewNC(viewName))
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = storyboard.instantiateViewControllerWithIdentifier(browserNC)
self.presentViewController(vc, animated: true, completion: nil)
case "link":
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
myStack.push(getViewNC(viewName))
let vc : UIViewController = storyboard.instantiateViewControllerWithIdentifier(getTipsInfo(viewName, sectionNumber: indexPath.section, tipOrder: indexPath.row).tipLinkName)
self.presentViewController(vc, animated: true, completion: nil)
default:
()
} // end switch
}

Assuming that you want to make this UITextView the first responder immediately upon it loading, you could put the following code inside of your awakeFromNib method inside of a custom UITableViewCell class.
self.myTextView.becomeFirstResponder()
This will make it so that the cursor will automatically be inside of myTextView whenever this cell loads, and the keyboard will come up as well.

Related

How to make a UIView transparent while presenting it from UITableViewCell with UITapGestureRecognizer?

I presented a UINib (custom AlertView) from UITableviewCell by tapping on UILabel. UINib is having two views, one is for custom alert and the background view is to show an alert view effect by making it transparent.
#objc func taptakeYourMedsDescriptionLabel(tapGestureRecognizer: UITapGestureRecognizer) {
let undectableVC = UndetectableAlertVC(nibName: "UndetectableAlertVC", bundle: nil)
undectableVC.view.backgroundColor = UIColor.black.withAlphaComponent(0.1)
UIApplication.shared.keyWindow?.rootViewController?.present(undectableVC, animated: true, completion: nil)
}
I also gave undectableVC.view.backgroundColor = UIColor.black.withAlphaComponent(0.1) in viewWillAppear of UndetectableAlertVC
Problem: The view is transparent while presenting it but soon after the view is presented it is changing to black color.
Requirement:
Can anyone help me with this?
Try This
let undectableVC = UndetectableAlertVC(nibName: "UndetectableAlertVC", bundle: nil)
undectableVC.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
undectableVC.modalPresentationStyle = .custom
undectableVC.modalTransitionStyle = .crossDissolve
self.navigationController?.present(undectableVC, animated: true, completion: nil)

Reuse parent ViewController storyboard file in Child ViewController

Presenting ViewController Using storyBoard:
if newViewController is in StoryBoard.we can present it using the following method.
let storyboard = UIStoryboard(name: "AViewController"), bundle: UIBundle.main)
let newViewcontroller = storyboard.instantiateInitialViewController() as? AViewController
self.present(newViewcontroller, animated: false, completion: nil)
Is it Possible to present a ViewController which is not in storyBoard but its parent viewcontroller has storyboard
I have create a B viewcontroller programatically (No StoryBoard) ,now I would like to present BViewController and it should use the AViewController StoryBoard?
class AViewController : UIViewController
{
//this class is in storyboard which is generic design that I want to use it in different ways.
}
class BViewController : AViewController
{
....//
}
e.g.
self.present(BViewController(), animated: false, completion: nil)?
when I present BViewcontroller it throws nil for parameters which are from super class.
I founded the answer to reuse the story board file or inherite the story board file.
object_setClass(Sets the class of an object.) will override instance of AViewController with BViewController Class. So on top of AViewController you can add some more methods.
when you have similar viewcontroller with small changes. you have to create different viewcontrollers. using this method you can create on basic viewcontroller with storyboard and reuse that viewcontroller .
class BViewController{
static func vcInstanceFromStoryboard() ->BViewController? {
let storyboard = UIStoryboard(name: "AViewController"), bundle: UIBundle.main)
let instance = storyboard.instantiateInitialViewController() as? AViewController
object_setClass(instance, BViewController.self) //
return (instance as? BViewController)!
}
.....
}
This is an example of how do we use it:
let vc = BViewController.vcInstanceFromStoryboard()
self.present(vc , animation : true)
Your code will work fine if your ViewController truly isn't in a Storyboard. All you have to do is instantiate it without a nibName, like this:
class ViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
Normal Storyboard ViewControllers rely on the coder init to be created, but you can create them normally with the nibName: nil initializer, as long as you don't have any outlets on it (which is your case since the ViewController is not on a storyboard)
Everything is possible programmatically. Not everything is possible through Interface Builder. Storyboards are just a component of Interface Builder.
To present a view controller programmatically from the root:
#objc private func presentViewController() {
guard let root = UIApplication.shared.keyWindow!.rootViewController else {
return
}
let destination = SomeViewController()
destination.transitioningDelegate = YourAnimationVendor()
destination.modalPresentationStyle = .custom
root.present(destination, animated: true, completion: nil)
}
You can omit the transitioning delegate (and the custom animation vendor) and present using a stock UIKit animation, like .fullScreen instead of .custom.
#objc private func presentViewController() {
guard let root = UIApplication.shared.keyWindow!.rootViewController else {
return
}
let destination = SomeViewController()
destination.modalPresentationStyle = .fullScreen
root.present(destination, animated: true, completion: nil)
}

Update particular row in tableviewcell in tableview in swift 3?

I am using tableviewcell.xib in table view. In that I have comment button, if I click on that I will navigate to another page so that I can comment, when I dismiss after commenting. It will come to tableview page, in that I want to update the comment count value without updating with service call . where I should add this code for updating cell.Please help me.
let indexPath = IndexPath(item: sender.tag, section: 0)
self.tableView.reloadRows(at: [indexPath], with: .automatic)
I am navigating like this
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let commentPage = storyBoard.instantiateViewController(withIdentifier: "postCommentsPage") as! PostCommentViewController
self.present(commentPage, animated: false, completion:nil)
What you need to do is to make one protocol like UpdateCommentCount and implement that protocol with your Controller where you are having this tableView after that in your PostCommentViewController make one instance property of type UpdateCommentCount, also in your tableController declare one property of type Int to hold the reference of tapped row.
protocol UpdateCommentCount {
func updateComment(with count:Int)
}
Now implement this UpdateCommentCount with yourController and add one Int property to hold the reference of tapped row and set it inside your button action where you are presenting your PostCommentViewController
class YourController: UIViewController, UpdateCommentCount, UITableViewDelegate, UITableViewDataSource {
var currentCommentRow = 0
//Your other methods
func commentButtonAction(_ sender: UIButton) {
currentCommentRow = sender.tag
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let commentPage = storyBoard.instantiateViewController(withIdentifier: "postCommentsPage") as! PostCommentViewController
commentPage.commentDelegate = self
self.present(commentPage, animated: false, completion:nil)
}
func updateComment(with count:Int) {
let dic = yourArray[self.currentCommentRow]
dic["commentCount"] = count
yourArray[self.currentCommentRow] = dic
let indexPath = IndexPath(item: self.currentCommentRow, section: 0)
self.tableView.reloadRows(at: [indexPath], with: .automatic)
}
Now in PostCommentViewController declare one instance property named commentDelegate of type UpdateCommentCount and after simply call its delegate method when you successfully post comment.
var commentDelegate: UpdateCommentCount
Call updateComment after successfully posting new comment.
commentDelegate.updateComment(with: newCount)
You can use NSNotification. Register the notification in that table view's viewDidLoad method. Than send notification before presenting the view as shown bellow..
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let commentPage = storyBoard.instantiateViewController(withIdentifier: "postCommentsPage") as! PostCommentViewController
NotificationCenter.default.post(name: Notification.Name(rawValue: myNotificationKey), object: self)
self.present(commentPage, animated: false, completion:nil)
Than reload table view in notification calling function.

UICollectionView is nil

I have a UIViewController in storyboard which hosts a collectionView which is referenced using a IBOutlet. However, now I am placing this inside of a PageViewController and referencing it like this, rather than with the use of a seque :
let initial = FeedCollectionViewController()
let viewControllers = [initial]
setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
The problem is that the collectionView is now nil.
Of course it's nil. You built your view controller in storyboard, so you should init it from storyboard. Like this:
let tabSb = UIStoryboard(name: "Main", bundle: nil)
let tabbarVc = tabSb.instantiateInitialViewController()

How to dismiss UIPopoverPresentationController on tap inside it. (iOS, Swift)

I've been successfully able to implement a popviewcontroller, which contains a tableview of 4 cells. I want to close the popViewController when the cell is selected, but I cannot seem to do this. In my tableViewController, I have a method inside didSelectRowAtIndexPath, which calls this MasterViewController's method "updateToSelectedTab". I am able to print out the indexpath of the selected cell here, but I cannot remove the popViewController when the cell is selected. How do I do this?
//Here is our MasterViewController class
#IBAction func pop(sender: AnyObject) {
let contentView = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("popViewController") as! PopViewController
contentView.modalPresentationStyle = UIModalPresentationStyle.Popover
contentView.preferredContentSize = CGSizeMake(aButton.frame.width, 240.0)
let popoverMenuViewController = contentView.popoverPresentationController!
popoverMenuViewController.delegate = self
popoverMenuViewController.permittedArrowDirections = UIPopoverArrowDirection.Any
popoverMenuViewController.sourceView = view
popoverMenuViewController.permittedArrowDirections = UIPopoverArrowDirection(rawValue:0)
popoverMenuViewController.sourceRect = CGRectMake(aButton.frame.origin.x, aButton.frame.origin.y - 60, aButton.frame.width, aButton.frame.height)
presentViewController(contentView, animated: true, completion: nil)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
//This method is called from didSelectRowAtIndexPath of the View Controller that handles the UIPopoverPresentationController
func updateToSelectedTab(tab: Int){
print("Current tab \(tab)")
//Need to dismiss controller here
}
All I had to do was add this code in select row at index path delegate method:
dismissViewControllerAnimated(true, completion: nil)

Resources