JSQMessagesViewController timestamp inside bubble - objective-c

I'm using JSQMessagesViewController in my chat app.
I would like to add a small timestamp text inside the bubble on its lower right corner.
I have searched a lot but could not find any way to accomplish this using the API provided.
Any idea how I can do this ?
Thanks,
Daniel

Just create a custom cell or xib and then when implementing the JSQ framework just use your custom cell in the
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView?.dequeueReusableCellWithReuseIdentifier("[YOURCUSTOMCELLIDENTIFYER]", forIndexPath: indexPath)
//Configure your cell here
return cell
}

Related

iOS Collection View Change Cell content on didSelectItemAt indexPath

I need to access to the particular cell and change its content dynamically on didSelectAt indexPath
func collectionView(_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath) {
if collectionView == self.trendHeaderView{
print(indexPath.row)
// Needs to access cell and change the
// content of cell i.e label text inside cell ??
}
}
I need to access to the particular cell
No, you don't. You should never meddle with a cell's contents directly. You need to access the data (the "model") that the collection view's data source is using. And you can easily do that, because you have the indexPath. Change the data, and reload the collection view so that it picks up the changes and displays them.
You can't change the cell's content directly in didSelectItemAt.
As you can see, in UICollectionView cell is reused by calling dequeReusableCell.
So I think, it's good to make model for that.
and change the model content in didSelectItemAt.
and Please call reloadData to redraw collectionview.

Can closure in swift be used for communication between 2 classes?

I have a custom cell for a UITableView. When user taps on a button in cell, user has to get navigated from the current ViewController1 to ViewController2. I have defined the button action in the custom cell class. But needs a call back to the ViewController1.
I tried using closure similar to how we use blocks in objective C. It works fine while using in the same class. But getting errors while using in 2 different classes.
You need to use delegate protocols there.
Example: Protocol for sending UserItem when something happened in cell:
protocol TappedUserDelegate: class {
func userInfoTapped(_ tappedUser: UserItem?)
}
In your controller:
extension Controller: TappedUserDelegate {
func userInfoTapped(_ user: UserItem?) {
// user is tapped user in cell
}
}
In your tableView func:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ........
cell.delegateUserTaps = self // for user info taps to perform segue
// ........
}
In your custom cell:
class CustomCell: UITableViewCell {
weak var delegateUserTaps: TappedUserDelegate? // for sending user info
// ........
func userInfoTapped() {
delegateUserTaps?.userInfoTapped(userItem) // <- send data to controller
}
}
When userInfoTapped will be called, your function in controller will be performed with this user.
I've given you an idea.
Hope it helps

Preventing contextual menu showing on specific cell in a view based NSTableView

Is there any way of preventing a contextual menu (and the associated selection "ring" around the cell view) being shown when right-clicking on a specific cell in a view-based NSTableView ?
I'm not talking about disabling the right-click action on ALL the cells, but only on specific ones.
I've obviously tried all the delegate methods dealing with selection changes but none works because the selectedRow property is not changing, only the clickedRow does.
So basically I'm looking for something equivalent to
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool
but for the clicked row not the selected row.
Note: the questions is about NSTableView on macOS and not the UITableViewon iOS.
I've found a way to do what I wanted, although looks like a little to involved for something that should be simpler. So I welcome any simpler solution.
It can be done by subclassing NSTableView :
class MyTableView : NSTableView {
override func menu(for event: NSEvent) -> NSMenu? {
let clickedPoint = self.convert(event.locationInWindow, from: nil)
let row = self.row(at: clickedPoint)
// no contextual menu for the last row
return row == self.numberOfRows - 1 ? nil : super.menu(for: event)
}
}
This example prevents the contextual menu to be shown for the last row, but a more generic solution could be implemented by adding a delegate with a method to return the menu for each cell.
Instead of subclassing NSTableView, a much easier approach is to set a menu delegate and remove all items within public func menuNeedsUpdate(_ menu: NSMenu) delegate method.
Example:
class MyViewController: NSViewController {
override func viewDidLoad() {
let menu = NSMenu()
menu.delegate = self
tableView.menu = menu
}
}
extension MyViewController: NSMenuDelegate {
public func menuNeedsUpdate(_ menu: NSMenu) {
//This will prevent menu from showing
menu.removeAllItems()
//Check if user has clicked on the cell or somewhere inside tableView
//area that is not populated with cells
guard tableView.clickedRow >= 0 else { return }
//Get model
let item = items[tableView.clickedRow]
//For cells that need context menu, add necessary menu items
if item.needsContextMenu {
menu.addItem(NSMenuItem(title: "Edit", action: #selector(tableViewEditItemClicked(_:)), keyEquivalent: "e"))
menu.addItem(NSMenuItem(title: "Delete", action: #selector(tableViewEditItemClicked(_:)), keyEquivalent: "d"))
}
}
}

ImageView Not Displaying on Reusable TableViewCell

I have a TableView and TableViewCell created on my ViewController. The cell will be reusable (importing name + photo from database). Currently only the name cell text shows up.
How can I get the image to show above the cell text(name). Or will I need to create a separate cell subclass? Trying to make something like this:
Storyboard Setup
Update
Added ImageView(inside the cell) to storyboard and made an outlet to FeedCell.swift:
#IBOutlet weak var setImage: UIImageView!
Added to ViewController's ViewDidLoad:
self.tableView.registerClass(FeedCell.self, forCellReuseIdentifier: "RestaurantCell")
Updated ViewControllers cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as UITableViewCell
var imageSet: PFObject?{
didSet{
self.fetchImage(restaurantArray[indexPath.row] as? PFObject, completionHandler: {
(image, error) -> () in
if image != nil {
FeedCell().setImage.image = image
cell.imageView?.image = image!
cell.imageView?.image = image
cell.accessoryView = UIImageView()
}else{
//alert user: no image or put placeholder image
}
})
}
}
return cell
}
You have a "RestaurantCell", but from the Storyboard screenshot you've included in your question, it looks like it's just a completely blank cell with an empty content view.
If you don't want to create a custom UITableViewCell, you should change that prototype RestaurantCell to have both a centered image and a label just underneath it, both exposed via properties that have unique tags set with them. Then, when the properties get set, you can update the view corresponding to the tag (e.g. view # 1 might be the image, view # 2 might be the name, etc.).
Or, you can simply subclass UITableViewCell and then you'll be able to use IBOutlets, which will be a lot cleaner versus using manual property setters and tags.
Then you can easily set the image and the label text and it should appear just beautifully in the Munchery app.
You might want to also include extra IBOutlets to set the Chef's imageView (Chef Alex is one of my favorites) and the cart button ("+Add", which I think swaps with "In The Bag"?).
EDITED TO BE MORE SPECIFIC
Get rid of "FeedCell().setImage.image = image". That's not doing anything good.
Change
let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as UITableViewCell
to:
let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as FeedCell
Also, is the IBOutlet in FeedCell connected to imageView or is the outlet named something else?

Load data to NSTableView in swift

I am new to IOS/IOX development. I tried many sites to load data to my table on OSX swift using NSTableView. But all was failure.
The procedure i did was refering View-Based NSTableView in Swift - How to
Drag and droped a NSTableView, which was perfectly seen when I run the code.
Selected the first column and gave Identifier as "List" after setting number of columns to 1
In the appdelegate.swift I pasted as
class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDataSource,NSTableViewDelegate {
func applicationDidFinishLaunching(aNotification: NSNotification?) {
}
func applicationWillTerminate(aNotification: NSNotification?) {
}
func numberOfRowsInTableView(aTableView: NSTableView!) -> Int {
println("reached 1")
return 10
}
func tableView(tableView: NSTableView, viewForTableColumn: NSTableColumn, row: Int) -> NSView {
println("reached 2")
var cell = tableView.makeViewWithIdentifier("List", owner: self) as NSTableCellView
cell.textField.stringValue = "Hey, this is a cell"
return cell
}
}
Then i tried to Set the delegate and datasource as the Appdelegate for the table view by selecting table and pointing to "App Delegate" in "Application Scene". But it was not linking
When i run the program , table with no cells was loaded
Any help is greatly appreciated.
The easiest way would be selecting your table view in the XIB file and then in the Utilities panel on the right chose the third icon from the right (the arrow pointing right). Also make sure you show the document outline by clicking the icon in the lower left of the Interface Builder window. From the Utilities panel you can just drag from the delegate and datasource circle to your AppDelegate in the document outline.
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
{
if tableView.identifier=="tableViewIdentifier" {
let cellView = tableView.makeViewWithIdentifier("List", owner: self) as! NSTableCellView
cellView.textField?.stringValue = "Hey, this is a cell"
return cellView
}
return nil
}
set identifier to tableview of dropped table also set identifier to table column, set the delegate and datasource to the view controller in which the table is contained.
In your case, when using storyboards, you should make your view controller a data source and delegate for your table view, because they're contained in one scene. The class itself is called ViewController in Xcode project templates.
So, just move the code from application delegate to view controller and connect all the things in storyboard.