Comments Input Accessory View
Instagram Firebase
Before we can render out our comments inside of the UICollectionView, we'll need to implement a section that contains the input components necessary. In this lesson, I'll go over a very simple way to implement a keyboard handler by using an inputAccessoryView property. Using this approach will allow the list above to interact with the input components naturally and easily.

Comments (25)
omari
6 years ago
Hey Brian. We would definitely prefer it, because the course is structured very well and easy to follow. I know you can't show us everything in detail but some points are necessary to build a good copy and have a goo UX. I understand that you omit stuff like the chat feature because we saw it in the firebase chat tutorial. But we never talked about some necessary stuff in other tutorials so please as you promised Brian implement following : --> User forgets password (Send email etc.) --> User tries to login or register and has wrong credentials. Notify the user about his mistakes like email is not valid etc (maybe with red color =) --> How can you block a user in our Instagram app and how can you make reports --> If you create the app the home feed is empty. It would be nice to have some suggestion based on the location or etc. who a user could possibly follow --> How can you edit your profile --> iOS notifications if someone liked you post or commented on your post or tries to follow you --> The most important feature for this app is the hashtag feature and searching for hashtags. This is what made Instagram so successful and is also part of other applications. Please as you promised implement these into the Instagram app. This would help us all. Otherwise our apps wouldn't be completely and this would be sad to build such great apps but missing key concepts. Thanks Brian
GeminixClown
6 years ago
The most requested feature is how to make pagination Omari, not to mean to offensive, but all feature you write above, you can figure it out by yourself in time... believe me... Pagination is more important and super tricky to implemented... imagine if Brian implement all the feature that you wanted. have you ever wondering if you make an app use firebase or another backend, when user refresh the post, if that user has 1000 post, how do you solved that Omari? believe me Pagination is more important issue in Firebase... no one teach about this in any tutorial you found in the internet.... Please Brian stick with Pagination
omari
6 years ago
Hello Clown, I never said that pagination isn't important but your reply is offensive in some way. The features I mentioned are very important and not only for this course. We need them for several other apps. I know that you have different preferences and strengths but think before you judge. I thought a lot of features and not all of them are very easy or intuitive to implement. Before purchasing the Instagram course I asked Brian wether the features I listed will be part of the course or not. He said that is going to implement them. This was before pagination was ever mentioned. I just wanted to remember Brian. I know that his time is limited and he can't show us everything therefore I just mentioned the most important key concepts. Nevertheless your answer is very unfair and I'm disappointed because thats not a constructive and good way of replying just to say hey stick to my preference the rest is easy. Thats unfair.!
GeminixClown
6 years ago
Your request 7 featured and im not say thats not important, but hey 7 againts 1, maybe u should think about the word "unfair" well let's hope Brian will teach us all of your requested feature and pagination... so if u still my replay is unfair, it is up to you... again from the first time i replay your comment, i never mean to be offensive to you, thanks Omari lets hope Brian will complete our requested feature.
omari
6 years ago
By unfair I mean the sequence... its like cutting the line in the supermarket - Just watch the Q&A from 16 April ;). Nevertheless hopefully we all will be satisfied with the course :)
Kenny Ho
6 years ago
Completely agree with you! Brian we would really appreciate it if you can help us out with these functions. Many of us a new to programming and learning how to implement these features will be a huge value added to our skill set. Anyways, we still appreciate your hard work and commitment into teaching this great course!
AlfieLBTA
5 years ago
You are asking the teacher to make your homework, this courses are intended for your to LEARN how to program IOS apps with real life examples but not to copy someapp to perfection. (Do you know how many programming hours the instagram developers put in already, and you are asking one guy to put those for 50 bucks on 40 20 minute lessons , be real man). The password thing is pretty straight forward if you read FireBase documentation Wrong credentials as EZ as making the input border red if firebase response is X Suggestions: make the page and present some users based on GPS positioning ( i bet stack overflow is swarming with examples of how to get those coordinates). Edit your profile: make a profile page and fill it with all the data you need then make that data set a json object inside your users branch in firebase. I agree with you on the hashtag, maybe thats highend backend server stuff which needs a whole course on itself, it isn't a simple array from a DB. Bottom line: i think you need to star thinking by yourself on some of that simple stuff you are asking for.
omari
6 years ago
Hello Clown, I never said that pagination isn't important but your reply is offensive in some way. The features I mentioned are very important and not only for this course. We need them for several other apps. I know that you have different preferences and strengths but think before you judge. I thought a lot of features and not all of them are very easy or intuitive to implement. Before purchasing the Instagram course I asked Brian wether the features I listed will be part of the course or not. He said that is going to implement them. This was before pagination was ever mentioned. I just wanted to remember Brian. I know that his time is limited and he can't show us everything therefore I just mentioned the most important key concepts. Nevertheless your answer is very unfair and I'm disappointed because thats not a constructive and good way of replying just to say hey stick to my preference the rest is easy. Thats unfair.!
gymmilo
6 years ago
Guys, I might have not read all the comments related, so I may miss some important points. But as I read this list of “Brian’s promises”, I can’t help thinking, ‘Oh, this is way too much.’ I don’t know how Brian promised, or whether he promised, then why he did so. He published the promotional video that we all watched before we purchased this course, and I believe Brian’s responsibility doesn’t go beyond the boundary of what he showed us in the video. Yes, it would be nice if he delivers more, as more is always better for customers like us, but it is something we should be grateful for, not what he should feel pressured for. I believe this course is certainly not about making a complete application. Did we really expect that? To learn how to make a complete Instagram app with a fifty-dollar course? Then why some ignorant company called Facebook hires so many programmers to run the program? I am not rich and I also ponder a lot when making any purchase decision, but I believe this course has already reached the point where I get a feeling of, ‘this is absolutely a steal!’ Because he shared so much of his skills and insight on YouTube for free, we now take it for granted and are accustomed to ask for more but we could certainly stay in the realm of being reasonable. If we pressure him for anything, I think it could only be to ask him nicely to build another Instagram course for advanced features and let him price again whatever amount he thinks the new course is worth. Then we can check feature sets covered in the course and decide whether to buy.
Fred van Rijswijk
6 years ago
Fred van Rijswijk
6 years ago
Agree
GeminixClown
6 years ago
Im a agree with u, i know some like push notification and other security feature are important too, but the logic Brian gives us until today is very greatit is more than $50, so we cant presure him more....
omari
6 years ago
Actually I don't understand why you answering questions that are directed to Brian but if you do so please read the comments and then answer. We said that we are grateful and satisfied with this course. We just had some wishes that we discussed in previous videos with Brian and now I just wanted to remember him Secondly to build a complete Instagram copy the feature list would be longer than x sites. I just mentioned a few very important points that are also relevant to other tutorials on the lets build that app website. We asking questions so that Brian gives us an answer. Please don't answer my questions because they are not supposed to be answered from anyone else than Brian. Otherwise it's a waste of time and I don't want to explain myself to people who have another motivation, wishes, goals etc.. Keep your personal opinion to yourself. The last point I would like to mention is that Brian's motivation isn't money. I don't have any problem to pay more but as a member since day one I know Brians motivation . So please don't understand it wrongly. I would appreciate it a lot if you give Brian the chance to answer our questions. If you have and other opinion you can write it in the q&a live stream but please not here.
Stephan Dowless
6 years ago
agree 100 percent. Brian is a great guy and I have learned SO much from him. Dude also has a life too, and can't spend all his time teaching us how to implement every single feature of a complex app like instagram. these videos are already EXTREMELY well structured and helpful beyond words, this is professional level programming. Anyone who complains about the course should understand these points, and also understand that part of development is teaching yourself things, people won't hold your hand every step of the way.
Ilyar Mnazhdin
6 years ago
Agree with you. Hey, Brian! Take our money and make another course!!! =)
Brian Voong
6 years ago
ivancantarino
6 years ago
Brian there's a simpler workaround to set the tab bar as hidden when presenting the CommentsController: What about going to HomeController didTapComment() delegate method and set the self.hidesBottomBarWhenPushed = true; then push the VC then set it again to false. Taking this approach it won't even show up when you're sliding back. :)
Jesus Adolfo
6 years ago
Has anyone to refresh the home feed multiple times? Sooner or Later I get error in line 140 of HomeController line 140 ish -> cell.post = posts[indexPath.item] fatal error: Index out of range I moved the posts.removeAll() to different places but that didn't help. Any advice?
omari
6 years ago
Jesus you can fix that by asking inside the cellforitemat method if the refresh is finished . So wrap everything with the following code ( But you also have to create a Uicollectionviewcell outside and then you can return inside if cellforitemat because the method expects you to return a UiCollectionViewcell. If you didn't understand ask again. override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { if !self.refreshControl.isRefreshing { let cell = ... } }
omari
6 years ago
This approach helped me to solve that issue. But still its a bit buggy and I hope Brian offers a great solution for that how we can handle the fetchPosts in a more efficient and better way.
omari
6 years ago
Forget to mention you also have to create the refreshcontrol outside of viewDidload let refreshControl = UIRefreshControl()
Jesus Adolfo
6 years ago
For some reason the navigation controller drag functionality to go back is not working for me...
omari
6 years ago
Hello Brian, I did everything like you but the keyboard does not appear :S
omari
6 years ago
Changed the hardware settings of the simulator and now the keyboard appears :)
anmol
6 years ago
What happened to your neck Brian? I can see a band aid there.
Brian Voong
6 years ago
anmol
6 years ago
Good to know. One issue I am facing with inputAccessoryView is if keyboard is there and I press back, it goes away perfectly and if I come back and click textField, the inputAccessoryView doesn't come up and keyboard is also not dismissing. Anything I did wrong or it'll be fixed in future videos?
Brian Voong
6 years ago
anmol
6 years ago
No still not working. Facing the same issue.
Brian Voong
6 years ago
anmol
6 years ago
Still facing the same issue. :(
smiller193
6 years ago
did you ever fix this issue I'm facing the same problem
smiller193
6 years ago
brian this didnt wok and I the input accessory view keeps getting stuck at the bottom
smiller193
6 years ago
Did anyone have a problem with the input accessory view being stuck at the bottom when you leave and come back while having the keyboard up. Which then results in the loss of the tab bar because the keyboard gets stuck in the raised position
johnrm9
6 years ago
Setting hidesBottomBarWhenPushed = true before pushing the CommentsController on the navigations stack and then hidesBottomBarWhenPushed = false hides the TabBar and restores it when coming back to HomeController. func didTapComment(post: Post) { hidesBottomBarWhenPushed = true let commentsController = CommentsController(collectionViewLayout: UICollectionViewFlowLayout()) navigationController?.pushViewController(commentsController, animated: true) hidesBottomBarWhenPushed = false }
Brian Voong
6 years ago
johnrm9
6 years ago
We can test if we're running on the Simulator using an extension (we can't use camera in the Simulator) - extension UIDevice { static var isSimulator: Bool { return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil } } // Disable camera button in nav bar and replace icon with "No_Camera" image - found on icons8.com // using 2x as in No_Camera@2x.png in Assets.xcassets // HomeController ... fileprivate func setupNavigationItems() { ... let cameraButton = UIBarButtonItem(image: #imageLiteral(resourceName: "camera3").withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(handleCamera)) if UIDevice.isSimulator { cameraButton.isEnabled = false cameraButton.image = #imageLiteral(resourceName: "No_Camera") } navigationItem.leftBarButtonItem = cameraButton }
johnrm9
6 years ago
I enhanced the anchor extension to include: centerXanchor, centerYanchor, heightAnchorEqualToWidthAnchor: Bool and centerAnchored: Bool. I used centerAnchored in LoginController to anchor Instagram logo in the logoContainer - let logoContainerView: UIView = { let view = UIView() let logoImageView = UIImageView(image: #imageLiteral(resourceName: "Instagram_logo_white")) ... view.addSubview(logoImageView) logoImageView.anchor(centerAnchored: true) // center Instagram logo return view }() and in PreviewPhotoContainerView to center the saveLabel - func handleSave() { ... DispatchQueue.main.async { ... self.addSubview(saveLabel) saveLabel.anchor(width: 150, height: 80, centerAnchored: true) // frame?! anchor! ... The extension anchor is a wee bit bigger: extension UIView { func anchor(topAnchor: NSLayoutYAxisAnchor? = nil, leftAnchor: NSLayoutXAxisAnchor? = nil, bottomAnchor: NSLayoutYAxisAnchor? = nil, rightAnchor: NSLayoutXAxisAnchor? = nil, paddingTop: CGFloat = 0, paddingLeft: CGFloat = 0, paddingBottom: CGFloat = 0, paddingRight: CGFloat = 0, width: CGFloat = 0, height: CGFloat = 0, centerXanchor: NSLayoutXAxisAnchor? = nil, centerYanchor: NSLayoutYAxisAnchor? = nil, heightAnchorEqualToWidthAnchor: Bool = false, centerAnchored: Bool = false) { translatesAutoresizingMaskIntoConstraints = false if let superview = superview, centerAnchored { centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true } if heightAnchorEqualToWidthAnchor { self.heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1).isActive = true } if let topAnchor = topAnchor { self.topAnchor.constraint(equalTo: topAnchor, constant: paddingTop).isActive = true } if let leftAnchor = leftAnchor { self.leftAnchor.constraint(equalTo: leftAnchor, constant: paddingLeft).isActive = true } if let bottomAnchor = bottomAnchor { self.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -paddingBottom).isActive = true } if let rightAnchor = rightAnchor { self.rightAnchor.constraint(equalTo: rightAnchor, constant: -paddingRight).isActive = true } if let centerXanchor = centerXanchor { self.centerXAnchor.constraint(equalTo: centerXanchor).isActive = true } if let centerYanchor = centerYanchor { self.centerYAnchor.constraint(equalTo: centerYanchor).isActive = true } if width > 0 { widthAnchor.constraint(equalToConstant: width).isActive = true } if height > 0 { heightAnchor.constraint(equalToConstant: height).isActive = true } } } Enjoy!
Mateen Kaj
6 years ago
I found it better to override "viewDidDisappear" method instead of "viewWillDisappear" in order to display hidden tabBar again which allows you to display tabBar only if the current viewController is completely dismissed.
Nick Stanislawski
5 years ago
How dod you add the container using the new safeAreaLayoutGuide
rebeloper
5 years ago
Make the containerView a subclass of ComposeView. // // ComposeView.swift import UIKit class ComposeView: UIView { // ........ // Other layout code and methods // ........ //We're adding the bottom constraint here to make sure we belong to window override func didMoveToWindow() { super.didMoveToWindow() if #available(iOS 11.0, *) { if let window = window { bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0).isActive = true } } } } Source: http://ahbou.org/post/165762292157/iphone-x-inputaccessoryview-fix https://gist.github.com/ahbou/d18a7450375f33c595802250117b2dde
rebeloper
5 years ago
In the end, the above will let the collectionView appear at the notch of the iPhone X (below the inputAccessoryView); not nice! So what I did is watched the device type and adjusted the height of the containerView accordingly. containerView.frame = CGRect(x: 0, y: 0, width: ScreenSize.width, height: DeviceType.isiPhoneX ? 50 + 44 : 50)
p31d3ng
5 years ago
this is working perfectly for iPhone X, thanks!
p31d3ng
5 years ago
portrait mode the height of safe zone is 44 pixel, but it's not the case in landscape mode. So maybe using subclass didMoveToWindow would be a better choice
鄭飛
5 years ago
hi brain in iOS 11 inputAccessoryView seems have bug, it cannot appear I've follow "https://stackoverflow.com/questions/44560734/custom-keyboard-inputaccessoryview-not-visible-in-ios-11" but still didn't work do you know any solution of it, or you know another implementation to achieve the same effect
Brian Voong
5 years ago
鄭飛
5 years ago
I tried to copy all the code of "CommentsController" to my project but it still buggy
鄭飛
5 years ago
and I also set the breakpoint on override var inputAccessoryView: UIView? { get { break point --> return containerView } } override var canBecomeFirstResponder: Bool { break point --> return true } but both of them didn't execute
Brian Voong
5 years ago
鄭飛
5 years ago
I am using a subclass of collectionViewController just like video and demo code, but somehow it cannot work
Aurélien Haie
5 years ago
Are you sure you still have this problem after watching the whole video? cause i had a problem at the beginning with the inputAccessoryView but I still continued watching and after you instantiate the containerView outside the inputAccessoryView, everything is fine. At least that's what happened to me
Johnny Wu
5 years ago
檢查 HomeController裡的 ---------------------------------- func commentButtonTapped(_ post: Post) { let layout = UICollectionViewFlowLayout() let commentsController = CommentsController(collectionViewLayout: layout) navigationController?.pushViewController(commentsController, animated: true) } ---------------------------------- 是否有正確? 有可能你打成let commentsController = UICollectionViewController((collectionViewLayout: layout) (我在iOS11下是正常的)
Polas Opel
5 years ago
Hey, I found a weird bug in my app and I have no clue why. Everything seems to work but when I open the CommentsController, type text in the textfield, go back to the HomeController, then go to the CameraController --> I cant take a picture and I also cant go back to the HomeController. The Buttons in the CameraController aren't triggering the actions and I don't know why because usually they work.
Brian Voong
5 years ago
tetraprism95
5 years ago
Hey Brian, I am having a problem where when I tap inside the textfield, the textField doesn't move up to show the keyboard and also the primary bug that I'm experiencing is when I tap it, the textField actually duplicates itself, where one is in its original position while the other exact textField is in the upper top left corner of the controller. And So I can hit the back button because it blocks it. I don't know why this is happening.
tetraprism95
5 years ago
Weird how this works. I fixed it but I don't know why it works like this. I had everything inside the inputAccessoryView, but when I create a new property of var containerView = { }() and put everything inside here, and delete all the code in inputAccessoryView only to return containerView. It seems to all work out...
allanaraujo
5 years ago
Can you put sample code here? Having similar issue.
Dipali Bajaj
5 years ago
Hi, textfield.anchor doesn't load anything for me. Instead I tried to use this (code inserted) but the application keeps crashing and doesn't load the textfield. textField.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true textField.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true textField.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true textField.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true textField.widthAnchor.constraint(equalToConstant: 0) textField.heightAnchor.constraint(equalToConstant: 0) textField.layoutMargins.bottom = 0 textField.layoutMargins.left = 0 textField.layoutMargins.right = 0 textField.layoutMargins.top = 0
mcolonnajr
5 years ago
be sure to add the Extension.swift file
mcolonnajr
5 years ago
.anchor is not working for me either. Not sure how to continue with the tutorial.
mcolonnajr
5 years ago
figured it out
rehan1531
5 years ago
why x and y is 0 , 0 in CGRect , it should be on the top of the view ? I didn't get it the frame of contianerView ?
ngsison
4 years ago
Hi Brian, I have the same question too. Also, why giving 100 as width of the containerView gives it full screen width?
ngsison
4 years ago
Brian, also, the accessory view looks bad on iPhone X. How can we move it to safe area? Is that possible using frame?
Brian Voong
4 years ago
startingpoint
4 years ago
if you see the textfield appear in the bottom of HomeController after you pop/dismiss the CommentsController... it seems to have something to do with the viewWillDisappear method blocking the CommentsController/textField from properly deinitializing. Someone mentioned similar solution, but you need to remove the viewWillDisppear & willWillAppear methods from the CommentsController, then add "commentsController.hidesBottomBarWhenPushed = true" in the delegate method didTapComment(), to restore hiding of the tab bar feature
frankcrest
4 years ago
HI Brian, This video is missing? I checked March 13, 2019
Brian Voong
4 years ago
frankcrest
4 years ago
Hi brian sorry, must have been a bug with vimeo, everything good now thx 4 reply
lxirsh
4 years ago
For anyone having difficulty getting the inputAccessoryView to play nice with the safe area in iPhone X (so that the textField isn't placed in the safe area), I found that only a couple of changes were necessary to get it working correctly. First, create subclass UIView like this: class CustomView: UIView { override var intrinsicContentSize: CGSize { return CGSize.zero } } Then, make "override var inputAccessoryView" a subclass of CustomView and add the line "containerView.autoresizingMask = .flexibleHeight" to the getter. Finally, in the constraints, change "bottom: containerView.bottomAnchor" to "bottom: containerView.layoutMarginsGuide.bottomAnchor". So the inputAccessoryView looks like this: override var inputAccessoryView: CustomView? { get { let containerView = CustomView() containerView.backgroundColor = .white containerView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50) let textField = UITextField() textField.placeholder = "Enter Comment" containerView.addSubview(textField) containerView.autoresizingMask = .flexibleHeight textField.anchor(top: containerView.topAnchor, left: containerView.leftAnchor, bottom: containerView.layoutMarginsGuide.bottomAnchor, right: containerView.rightAnchor, paddingTop: 8, paddingLeft: 8, paddingBottom: 8, paddingRight: 8, width: nil, height: nil) return containerView } } I just adapted the answer here on stackoverflow: https://stackoverflow.com/a/46510833/5625785
lxirsh
4 years ago
Actually, for the anchor extension like Brian used, it would look like this: textField.anchor(top: containerView.topAnchor, left: containerView.leftAnchor, bottom: containerView.layoutMarginsGuide.bottomAnchor, right: containerView.rightAnchor, paddingTop: 8, paddingLeft: 8, paddingBottom: 8, paddingRight: 8, width: 0, height: 0)
Brian Voong
4 years ago
lxirsh
4 years ago
Awesome. I'm curious to see how you solved it.
yaostyle
4 years ago
[By: 08/28/2019] If you find issue displaying inputAccessoryView, I've found the following solution: 1.) REMOVE viewdidAppear() & viewDidDisappear() in CommentsController.swift 2.) Create a custom UIView as the custom type of containerView: class CustomView: UIView { override var intrinsicContentSize: CGSize { return .zero } } 3.) Replace UIView() to CustomView(): 3a.) inputAccessoryView: CustomView?{...} 3b.)let containerView = CustomView() 4.) Add additional following code to didTapComment() {...} "before" the navigationController?.pushViewcontroller(..): commentsController.hidesBottomBarWhenPushed = true
yaostyle
4 years ago
CORRECTION: 1.) REMOVE viewDidAppear() & viewDidDisappear() OR "viewWillAppear() & viewWillDisappear()" in CommentsController.swift
Kyle Griffin
3 years ago
Fire
Kyle Griffin
3 years ago
Thank God I found your channel and courses dude. I'm coming from web dev and am used to html, css, React, Node, etc... Laying out these UIs programmatically is so much easier and makes so more sense with my background. I really did not want to deal with the storyboards!
HELP & SUPPORT