Transfer Data to WebView - ios

I'm trying to transfer data to the WebView by clicking on the cell with the following code:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath:
IndexPath) {
let storyboard = UIStoryboard(name: "App", bundle: nil)
let popup = storyboard.instantiateViewController(withIdentifier: "taskWebVieww")
as! taskWebView
popup.taskVar = ("https://example.com/m_task?id="+self.tskid[indexPath.row]
+"&uid="+UserDefaults.standard.string(forKey: "userID")!)
self.present(popup, animated: true, completion: nil)
}
So it's really OK but I'm getting correct data only to the next click.
Firstly it's nill, secondly, it's opening the first value, and so so
WebView code:
var taskVar: String = "undefined"
override func viewDidLoad()
{
webView.loadRequest(URLRequest(url: URL(string:taskVar)!))
super.viewDidLoad()
}

Use didSelectRowAt instead of didDeselectRowAt

Related

How to enlarge tableView on scroll?

I'm sorry if this is a duplicate. I tried to review similar questions in SO - still doesn't quite make me understand how to deal with this.
I have a tableView, three textViews and a UIButton. When the user scrolls the tableView, the tableView should pushes the textFields and the button out the image and take up more space. When that is done I want to continue scrolling through the cells.
(I want one of the textFields to always remain and still show the title.)
I think I need to put the textViews and button above the tableView inside a tableView header after which I need to set certain constraints between the UIView above the tableView and tableView itself. Then I need to play around with the UIScrollViewDelegate and calculate something.
As you guys can probably tell, I'm relatively new in programming and I believe this i why I don't quite understand the related questions. And as you can probably tell too, why I am pretty damn confused about how to solve my problem!
Here's a photo of the VC:
I wan't the tableView to go and cover the 'AddNewPersonBtn' and the two bottom textView - leaving only the top textView, the navigationBar and the tableView on the screen. --> Until you then scroll down again and the rest will be visible again.
And here goes the code for the VC:
import UIKit
import RealmSwift
class AllPersonsInYourDiary: UIViewController, UITableViewDelegate, UITableViewDataSource {
var diary: Diaries?
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var showingDiaryName: UILabel!
#IBOutlet weak var showingDiaryQuestion: UILabel!
#IBOutlet weak var showingExtraIdentifer: UILabel!
#IBOutlet weak var diaryTheme: UIImageView!
#IBOutlet weak var diaryPhoto: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.tableFooterView = UIView()
self.tableView.tableHeaderView = UIView()
}
override func viewWillAppear(_ animated: Bool) {
tableView.reloadData()
showDiaryIdentifiers()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func createNewPersonButton () {
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"PersonViewController") as! PersonViewController
controller.mode = .create
controller.diary = diary
self.navigationController?.pushViewController(controller, animated: true)
}
#IBAction func showEditFunc () {
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SettingsVC") as! SettingsVC
controller.diary = diary
self.navigationController?.pushViewController(controller, animated: true)
}
func showDiaryIdentifiers () {
self.showingDiaryName.text = diary?.diaryName
self.showingDiaryQuestion.text = diary?.diaryQuestion
self.showingExtraIdentifer.text = diary?.diaryExtraIdentifier
self.diaryTheme.image = UIImage(data: diary?.diaryTheme ?? Data()) ?? UIImage(named: "Blank")
// self.diaryPhoto.image = UIImage(data: diary?.diaryPhoto ?? Data ()) ?? UIImage(named: "Blank")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return diary!.people.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Person1", for: indexPath) as! PersonCell
let date = DateFormatter.localizedString(from: (diary?.people[indexPath.row].dateCreated)!, dateStyle: .short, timeStyle: .none)
cell.personName.text = diary?.people[indexPath.row].name
cell.personAnswer.text = date
cell.personPhoto.image = UIImage(data: diary?.people[indexPath.row].photo ?? Data()) ?? UIImage(named: "PortaitPhoto")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"PersonViewController") as! PersonViewController
controller.person = diary?.people[indexPath.row]
controller.diary = diary
controller.mode = .show
self.navigationController?.pushViewController(controller, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let alert = UIAlertController(title: "Are you sure you wish to delete person?", message: "", preferredStyle: .alert)
let action = UIAlertAction(title: "No thanks!", style: .cancel)
let action1 = UIAlertAction(title: "Delete!", style: .destructive, handler: { _ in
let realm = try! Realm()
try! realm.write {
guard let person = self.diary?.people[indexPath.row] else {
return
}
self.diary!.people.remove(at: indexPath.row)
realm.delete(person)
}
tableView.deleteRows(at: [indexPath], with: .fade)
})
alert.addAction(action)
alert.addAction(action1)
present(alert, animated: true)
} }
}

TableView Cell Selection not working properly

Trying MVVM design pattern.
Created a tableView in storyboard and in FirstViewController added below code :
#IBOutlet weak var menuTblView: UITableView!
let menuViewModel = MenuTableViewModel()
override func viewDidLoad() {
super.viewDidLoad()
self.menuTblView.dataSource = menuViewModel
self.menuTblView.delegate = menuViewModel
menuViewModel.delegate = self
menuTblView.register(UINib.init(nibName: "MenuTableViewCell", bundle: nil), forCellReuseIdentifier: "MenuTableViewCell")
menuTblView.separatorStyle = .none
}
and created a MenuTableViewModel having the tableviewDelegate and tableViewDatasource methods.
In MenuTableViewModel added the didSelectRowAt:
extension MenuTableViewModel:UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate.present()
}
}
protocol MenuTableViewModelDelegate : class {
func present()
}
and created a prototcol to present a SecondViewController.
In FirstViewController added below code:
extension FirstViewController : MenuTableViewModelDelegate {
func present() {
let asd = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.present(asd, animated: true, completion: nil)
}
}
The problem is the SecondViewController appears after clicking the tableViewCell twice.
EDIT:
MenuTableViewModel code :
class MenuTableViewModel: NSObject {
var delegate:MenuTableViewModelDelegate!
}
and in FirstViewController - ViewDidLoad added :
menuViewModel.delegate = self
Thanks #koropok for the solution. Added below code and it worked :
DispatchQueue.main.async {
self.delegate.present()
}
but why I have to do this.
Infact If I am adding below code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
//DispatchQueue.main.async {
self.delegate.present()
//}
}
then also it's working fine.
My approach is wrong or I am missing something here.

Need to double tap on cell to present modally VC

I am generating table cell.
cell2 = settingsTableView.dequeueReusableCell(withIdentifier: "ModuleCell", for: indexPath) as! ModuleCell
It looks fine, the cell has tag = 2000.
In override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath), I am checking the tag end if tag == 2000 I want to present modal view. I am doing that in this way
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let modalView = storyboard.instantiateViewController(withIdentifier: "ModalView")
present(modalView, animated: true, completion: nil)
Then in modalView I have a button which should dismiss modalView, what's happening as expected.
#IBAction func saveAndClosePopup(_ sender: UIButton) {
UserDefaults.standard.removeObject(forKey: "ActiveCantachoOptions")
UserDefaults.standard.set(Modules.activeCantachoOptions, forKey: "ActiveCantachoOptions")
self.dismiss(animated: true, completion: nil)
}
However, when I want to immediately present modalView again, sometimes it's okay, but sometimes I need to hit two times on the cell, which should show modalView. After the first hit, there is no difference if I hit the cell again in 1 second or in 30 seconds. The modalView will appear after the second one. What is the cause?
Try this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let modalView = storyboard.instantiateViewController(withIdentifier: "ModalView")
self.present(modalView, animated: true) {
tableView.deselectRow(at: indexPath, animated: false)
}
}

How to pass only one key value pair from array?

The following is my json response....
{"Doctor":[{"doctorname":"ANBU SURESH RAO, D.ORTHO., MSORTHO.,","presid":"1008"}]}
The following is my viewcontroller code.......
let parameters: Parameters=["hnum":hnum!]
Alamofire.request(URL_USER_LOGIN, method: .post, parameters: parameters).responseJSON
{
response in
let result = response.result
if let dict = result.value as? Dictionary<String,AnyObject>{
if let innerDict = dict["Doctor"]{
self.namesarray = innerDict as! [AnyObject]
self.jsontable.reloadData()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return namesarray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell
let name = namesarray[indexPath.row]["doctorname"]
cell?.lbldocname.text = name as? String
flag = !flag
flagcheck()
return cell!
}
This view controller loads only my doctor name, so when i click the doctor name I want the presid only to be passed on to the next view controller.... I tried with prepareForSegue it didnt work....any ideas????
tableView:didSelectRowAtIndexPath:
Tells the delegate that the specified row is now selected. Use indexPath to locate the new selected row in tableView.
Check my previous SO ans for details.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let pressId = namesarray[indexPath.row]["presid"]
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController ") as? SecondViewController {
viewController.pressId= pressId
if let navigator = navigationController {
navigator.pushViewController(viewController, animated: true)
}
}
}
Declare a global variable pressId in SecondViewController so that you can access it from your current controller class.
Declare a global variable selectedPresId. Implement didSelectRowAtIndexPath method and in that method set the pres id in that global variable
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedPresId = namesarray[indexPath.row]["presid"]
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
In prepareForSegue do this
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailSegue" {
let vc = segue.destination as! ViewController
vc.selectedPresId = selectedPresId
}
And in your second view controller create a property with the name - selectedPresId so that you can set it in above line vc.selectedPresId

TableView is Nil

I have the following class:
import UIKit
import CloudKit
class FirstViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var listTableView: UITableView!
var list: TLListModel!
var specificList: CKRecord!
override func viewDidLoad()
{
super.viewDidLoad()
let myContainer = CKContainer.default()
list = TLListModel(container: myContainer, viewController: self)
if(listTableView != nil){
listTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("number of items: %i", list.lists.count)
return list.lists.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = listTableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell
let list: CKRecord = self.list.lists[(indexPath as NSIndexPath).row]
cell.textLabel?.text = list.value(forKey: "ListName") as? String
cell.textLabel?.font = UIFont (name: "Slim Joe", size: 20)
cell.accessoryType = .disclosureIndicator
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("This object has been selected")
print(self.list.lists[(indexPath as NSIndexPath).row])
specificList = self.list.lists[(indexPath as NSIndexPath).row]
performSegue(withIdentifier: "TLSpecificListSegue", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "TLSpecificListSegue"{
if let destinationVC = segue.destination as? TLSpecificListViewController{
destinationVC.listObject = specificList
}
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
let cloudkit = TLCloudKitHelper()
cloudkit.deleteListItem(self.list.lists[(indexPath as NSIndexPath).row], callback: { (listName) in
TLAlertHelper.notifyUser("List Deleted", message: NSString(format: "List for %# successfully deleted", listName) as String, sender: self)
let myContainer = CKContainer.default()
self.list = TLListModel(container: myContainer, viewController: self)
DispatchQueue.main.async {
self.listTableView.reloadData()
}
})
}
}
}
When I call it from another view controller using the following method:
#IBAction func createListAction(_ sender: AnyObject) {
let cloudkit = TLCloudKitHelper()
let listArray = createListFromTextField(textInputArea.text)
if(!(listNameTextField.text?.isEmpty)!){
cloudkit.createList(listNameTextField.text!) { (response) in
let listId = response
if (!listArray.isEmpty){
for item in listArray{
cloudkit.saveItemRecord(item, listId: listId, recordName: response)
}
}
let fvc: FirstViewController = FirstViewController()
DispatchQueue.main.async {
self.present(fvc, animated: true, completion: nil)
}
}
}else{
TLAlertHelper.notifyUser("Give the list a name", message: "You need to give you list a name...", sender:self)
}
}
I get an error saying fatal error: unexpectedly found nil while unwrapping an Optional value
I don't understand why I am getting this error. I've tried looking at the answers here: Simple UITableView in Swift - unexpectedly found nil but I none of those answers helped. Can someone tell me why this this crashing and how I can fix it?
The problem is this line:
let fvc: FirstViewController = FirstViewController()
This creates a blank FirstViewController instance — one completely unconnected with the interface you designed in the storyboard. Its view is empty. It has no table view in it. Therefore, since there is no table view, there is no outlet connection from any table view, and listTableView remains nil.
What you want to do is get the FirstViewController instance from the storyboard, the one whose interface you have already designed in the storyboard. You can do that by talking to the storyboard and using the FirstViewController's identifier, i.e., call instantiateViewController(withIdentifier:). (You might have to give the FirstViewController in the storyboard an identifier for this purpose.)
EDIT This is such a common mistake that I've written a blog post about it: http://www.programmingios.net/dont-make-a-new-instance-by-mistake/

Resources