I want to mimic Instagram's tabbar functionality, where the middle option acts as a button that triggers a modal slide up segue instead of switching views like a normal tabbar button.
I don't know the correct way of doing this, but I'm trying to place a button directly over the middle tabbar button, but when pressing it it triggers the tabbar button instead of the normal button.
let count = CGFloat(tabBar.items!.count)
let itemSize = CGSize(width: tabBar.frame.size.width / count, height: tabBar.frame.height)
for (index, _) in tabBar.items!.enumerate() {
if index == 2 {
let xPosition = itemSize.width * CGFloat(index)
let backgroundButton = UIButton(frame: CGRect.init(x: xPosition, y: 0, width: itemSize.width, height: itemSize.height))
backgroundButton.backgroundColor = UIColor.redColor()
backgroundButton.addTarget(self, action: #selector(MainTabBarController.testButton), forControlEvents: .TouchUpInside)
//testButton just triggers a print statement for now
tabBar.insertSubview(backgroundButton, atIndex: 1)
}
}
When I press the middle button, it just triggers the normal view switching like with any other tabbar button, and does not print anything out meaning the overlayed button is never trigger.
Is there somewhere I went wrong, or better yet is there a better way of doing this? Prehaps making the tabbar button itself trigger a modal segue instead of the typical tabbar button behavior?
Related
Background: I am creating a button with an image and a label. I add the label to the button with button.addSubview(labelName) and then I add the button to the main view with self.view.addsubview(buttonName). I am creating all views programatically and with UIKit. I do not use SwiftUI or Storyboard.
Problem: When pressing the button and holding the press, by default the button image automatically gets darker and loses color (I do not know what this animation or action is called, but I guess it's some kind of default button press/click action). The gif below shows this animation.
The problem is, only the background image of the button is affected. The label and the label background, that I added to the button, are not effected by this dim animation.
What I want to achieve: I want the label and the label background to get the same dim effect, when the button is pressed. I don't like the way the label stands out with its bright colors while the button is pressed. Do I need to recognize the click and add some kind of dim animation to all childviews of the button manually or should I avoid adding labels to buttons like I did in the code below?
Simplified code for testing:
func doStuff(){
let testbutton = UIButton(frame: CGRect(x: self.view.frame.width/4, y: 100, width: 200, height: 130))
let testImg = UIImage(named: "rand.jpeg")
testbutton.setImage(testImg, for: .normal)
testbutton.addTarget(self, action: #selector(otherStuff), for: .touchUpInside)
let label = UILabel(frame: CGRect(x: testbutton.bounds.origin.x+20, y: testbutton.bounds.origin.y+20, width: 150, height: 50))
label.text = "NOT EFFECTED"
label.backgroundColor = .red
testbutton.addSubview(label)
self.view.addSubview(testbutton)
}
I want to show something when the dial pop up view shown like the screen capture, please how can I do with Swift?
I didn't quite get that question but if you wanna do something when you keyboard pops up you can do it in searchBarTextDidBeginEditing() which is an delegate method for UISearchBar
https://developer.apple.com/documentation/uikit/uisearchbardelegate/1624303-searchbartextdidbeginediting
if you wanna know more about custom UIAlert than refer this YouTube video
https://www.youtube.com/watch?v=u6TpJrZNuPU
if You wanna present something when your actionSheet is presented than you can directly add the animation programmatically after presenting the Alert
for example I presented a view after presenting an UIAlerActionSheet
self.present(alert, animated: true)
let view1 = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
view1.backgroundColor = UIColor.red
view.addSubview(view1)
here view1 is presented and when needed you can remove that view1 from its superView so that it will vanish
view1.removeFromSuperview()
I have three tabs in my tabbar controller and I want to switch between these tabs just like tinder switches the tab using finger touch. I have done it using UISwipeGestureRecognizer but its not exactly same as that of Tinder (the dating app ) swiping.
I have added UISwipeGestureRecognizer on one of the Tabbar controller and then added the function to change the tabbar selected index. But the animations is not controlled by finger touch. I want the swiping should be controlled by finger touch.
I think the best way to do it is to put all your tab views in a UIScrollView. You place them next to each other.
Implement the scroll view delegate methods in your tabbarController.
You'll probably need scrollViewDidEndScrollingAnimation and scrollViewDidEndDecelerating to know on which view you are when the user stops scrolling, like this:
let page_width=UIScreen.main.bounds.width
let page=Int(floor((scrollView.contentOffset.x-page_width/2)/page_width)+1)
Here, I assume each of your tab view is the same size as the screen.
I am bit late but I found my ans -
I have created 4 UIviewcontrollers programatically and then
created an array of it.
var views = [CareTeamTableViewController(),VFCChatQViewController(), NewAccountViewController(), ShareViewController()]
Then I added a scrollview in my main UiViewController
private func initMainScroll() {
scrollView = UIScrollView.init()
scrollView?.delegate = self
scrollView?.showsHorizontalScrollIndicator = false
scrollView?.isPagingEnabled = true
self.view.addSubview(scrollView!)
}
and then added the views array like :
func setupScrollView(complete:()->()) {
scrollView?.frame = views.first!.view.frame
scrollView?.contentSize = CGSize(width: CGFloat(views.count) * UIScreen.main.bounds.width, height: 0)
_ = views.map({ addViewToScrollView($0) })
_ = views.map({ $0.view.frame.origin = CGPoint(x: CGFloat(views.index(of: $0)!) * UIScreen.main.bounds.width, y: 0) })
complete()
}
func addViewToScrollView(_ viewController: UIViewController) {
scrollView?.addSubview(viewController.view)
viewController.willMove(toParentViewController: self)
addChildViewController(viewController)
}
I have created a bottom sheet and within the bottom sheet I have added a button to call another subview. The code for calling this second subview is:
func addSettings() {
let settingsVC = SettingsViewController()
if !settingsVC.view.isDescendant(of: self.view) {
self.addChildViewController(settingsVC)
self.view.addSubview(settingsVC.view)
settingsVC.didMove(toParentViewController: self)
// 3- Adjust bottomSheet frame and initial position.
let height = view.frame.height
let width = view.frame.width
settingsVC.view.frame = CGRect(x:0, y:self.view.frame.maxY, width: width, height: height)
} else {
// 2- Add bottomSheetVC as a child view
settingsVC.view.removeFromSuperview()
}
}
Whenever I call this function it adds another subview. If I press the button again and call this function again another SettingsViewController is added and this repeats every time I click the button.
Ideally I would like for this function to check if the SettingsViewController subview already exists and if it does then don't add another subview.
Any ideas?
I am using the AKSwiftSlideMenu project from the web and trying to put an activity indicator so it will display the indicator when the user pressed the menu bars on the top right. I tried everything. is there a way once the user pressed the 3menubar at the top to display a activity indicator until the menu appear from the side.
I do some database processing to build the menu item before the slide out.
Since AKSwiftSlideMenu is using UINavigationController, you can just add UIActivityIndicator on the right side of the navigation controller.
Something like that:
func showActivityIndicator() {
let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
let barButton = UIBarButtonItem(customView: activityIndicator)
self.navigationItem.setRightBarButton(barButton, animated: true)
activityIndicator.startAnimating()
}
Don't forget, you need to prevent the Segue from happening, and halt the program until you are done loading.