I have created a table view cell in story board and i created a cocoa touch class for it.In that it will have one button, so here i want to navigate to another view controller on clicking on the button programmatically.
This my code
#IBOutlet weak var findOutButton: UIButton!
override func awakeFromNib()
{
super.awakeFromNib()
findOutButton.addTarget(self, action: Selector(("action:")), for: UIControlEvents.touchUpInside)
}
func action(sender: UIButton) {
let vc5 = self.storyboard.instantiateViewController(withIdentifier: "DescriptionViewController") as? DescriptionViewController
self.navigationController?.pushViewController(vc5!, animated: true)
}
Here its showing error in this line
let vc5 = self.storyboard.instantiateViewController(withIdentifier: "DescriptionViewController") as? DescriptionViewController
`
like "value of type 'TableViewCell' has no member 'storyboard'.
Thanks in advance.Help me to clear out the error.
You cannot access self.storyboard from your UITableCell. You should navigate from the main ViewController, that contains your UITableView. And for this you need to use delegates. At top of your UITableCell class add this :-
protocol CustomTableDelegate {
func DelegateButtonPressed()
}
class YourClass : UITableViewCell{
var delegate : CustomTableDelegate? = nil
override func awakeFromNib()
{
super.awakeFromNib()
findOutButton.addTarget(self, action: Selector(("action:")), for: UIControlEvents.touchUpInside)
}
func action(sender: UIButton) {
self.delegate?.DelegateButtonPressed()
}
}
And In your main View Controller in which you have your UITableView, in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourClass", for: indexPath) as! YourClass
cell.delegate = self
return cell
}
And also add delegate as :-
class YOURVIEWCONTROLLER:UIViewController, CustomTableDelegate{
func DelegateButtonPressed(){
let vc5 = self.storyboard.instantiateViewController(withIdentifier: "DescriptionViewController") as? DescriptionViewController
self.navigationController?.pushViewController(vc5!, animated: true)
}
}
Let me know if you find any difficulty using this.
Create Completion Block For getting Button Action on View Controller Class
class YourCellClass : UITableViewCell{
var completionBlock : ((_ sender : UIButon)->())?
override func awakeFromNib()
{
super.awakeFromNib()
findOutButton.addTarget(self, action: Selector(("action:")), for: UIControlEvents.touchUpInside)
}
func action(sender: UIButton) {
completionBlock?(sender)
}
}
In View Controller Execute the Block
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellClass", for: indexPath) as! YourCellClass
cell.completionBlock = { (sender) -> Void in
/* Here sender is button refrence so you can modify property of the button also */
let vc5 = self.storyboard.instantiateViewController(withIdentifier: "DescriptionViewController") as? DescriptionViewController
self.navigationController?.pushViewController(vc5!, animated: true)
}
return cell
}
Related
After ios update to 13.4.1 to able to detect tap gesture in WKWebView, my code as follow:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(viewTap) )
tapGesture.delegate = self
webview.addGestureRecognizer(tapGesture)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
#objc func viewTap() {
print("tap on viewTap...")
}
I want to implement my custom MenuController once user selects a text. I am using the below code to do that, I subclassed WKWebview and implemented below
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
super.init(frame: frame, configuration: WKWebViewConfiguration())
enableCustomMenu()
}
func enableCustomMenu() {
let menuController = UIMenuController.shared
let testmenu = UIMenuItem(title: "Test", action: #selector(test))
menuController.menuItems = [testmenu]
}
func test(){
var text = ""
self.evaluateJavaScript("document.getSelection().toString()") { (data, error) in
text = data as! String
}
print(text)
}
override func becomeFirstResponder() -> Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
switch action {
case #selector(test):
return true
default:
return false
}
}
This used to work fine for UIWebview, but in WKWebview, in the canPerformAction we are no longer getting copy, lookup and share actions so these guys are not getting removed.
I had this problem too, I found that you can customize your WKwebview by overriding the function canPerformAction
here is an article about it .
It worked for me!
Hope that help you.
I was writing a simple WebView in Swift, but everytime I try to launch it in the iOS Simulator I get these errors. What is going wrong?
import UIKit
class ViewController: UIViewController {
#IBOutlet var webview: UIWebView
var urlpath = "http://www.google.de"
func loadAddressURL(){
let requesturl = NSURL(string: urlpath)
let request = NSURLRequest(URL: requesturl)
webview.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAddressURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Error:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
self uiwebview.ViewController 0x7987fc70 0x7987fc70
request NSURLRequest * 0x78ebfc40 0x78ebfc40
requesturl NSURL * "" 0x78ec0040
You simply haven't connected your UIWebView to the webview class property
Open the assistant editor, show your xib or storyboard at left, your view controller source file at right, click on the circle at the left of the webview property and drag into the UIWebView control. Once the connection is established, run the app and it should work now
I guess you get a white page because you test on the simulator. If you test on a real device you should be fine.
You need to put "!" after 'UIWebView' and unwrap "requesturl" to get your String value otherwise it's been an optional and you get error.
import UIKit
class WebViewController: UIViewController {
#IBOutlet var webview: UIWebView!
var urlpath: String = "http://www.google.de"
func loadAddressURL(){
let requesturl = NSURL(string: urlpath)
let request = NSURLRequest(URL: requesturl!)
webview.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAddressURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
i wan't to use UITableView.AllowsMultipleSelectionDuringEditing with Monotouch.Dialog. If the property is set to true, the click on the table (with edit mode enabled) seems to be ignored (no selection happens). If there is an Element.Tapped, it will be executed. In my current implementation it will push a new UIView to the NavigationController, but this is not what you expect in edit-mode.
You can reproduce the behaviour with the monotouch.dialog-sample project, just change the EditingDialog Constructor (DemoEditing.cs:57) to the following:
public EditingDialog (RootElement root, bool pushing) : base (root, pushing)
{
TableView.AllowsMultipleSelectionDuringEditing = true;
}
Is there a way to use AllowsMultipleSelectionDuringEditing? If yes, what's wrong with my approach?
I just had the same problem with my own code. The problem is that some of the MonoTouch.Dialog elements have their cell SelectionStyle set to UITableViewCellSelectionStyle.None.
I solved it by sub-classing Source or SizingSource:
public class MyTableViewSource : Source
{
public MyTableViewSource(DialogViewController container) : base(container)
{
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = base.GetCell(tableView, indexPath);
cell.SelectionStyle = UITableViewCellSelectionStyle.Gray; // something other than None
return cell;
}
}
Then in your DialogViewController:
public class MyDialogController : DialogViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
// setup root element
Root = new RootElement();
// . . .
TableView.Source = new MyTableViewSource(this);
TableView.AllowsMultipleSelectionDuringEditing = true;
}
}
Using Miguel de Icaza's Patterns for Creating UITableViewCells, I have created a custom UITableViewCell and turned that into a MonoTouch.Dialog Element. I'm using the elements API to create an edit form, using a few of my custom elements.
I'm trying to figure out how to respond to the deletion of the element. My custom element has a reference to the record it represents in the database. I want to respond to a deleted event in the same way I would respond to a Selected event, where I get the DialogViewController, UITableView, and NSIndexPath. Assuming such an event existed for an Element that I can respond to, I would fire a delete statement to the database with the given record id.
Based on Miguel's answer, I added a public Delete method to the sub classed Element called MyDataElement.
public class MyDataElement : Element {
static NSString key = new NSString ("myDataElement");
public MyData MyData;
public MyDataElement (MyData myData) : base (null)
{
MyData = myData;
}
public override UITableViewCell GetCell (UITableView tv)
{
var cell = tv.DequeueReusableCell (key) as MyDataCell;
if (cell == null)
cell = new MyDataCell (MyData, key);
else
cell.UpdateCell (MyData);
return cell;
}
public void Delete() {
Console.WriteLine(String.Format("Deleting record {0}", MyData.Id));
}
}
Then over on my sub classed DialogViewController, I handle the CommitEditingStyle method, cast the element as MyDataElement, then call the Delete method:
public class EntityEditingSource : DialogViewController.Source {
public EntityEditingSource(DialogViewController dvc) : base (dvc) {}
public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
{
// Trivial implementation: we let all rows be editable, regardless of section or row
return true;
}
public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
{
// trivial implementation: show a delete button always
return UITableViewCellEditingStyle.Delete;
}
public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
{
// In this method, we need to actually carry out the request
var section = Container.Root [indexPath.Section];
var element = section [indexPath.Row];
//Call the delete method on MyDataElement
(element as MyDataElement).Delete();
section.Remove (element);
}
}
You would have to modify the source to handle the delete event in the Source class and dispatch that message to the Element, in the same way that it is done for the other events.