UIButton and UIScrollView - iphone

I have a UIScrollView that contains a long image, whose height is way more than a screen could hold at the current time. Now I want to place buttons all over the image. However, some of the buttons are below the view that you see when you haven't scrolled yet and after scrolling to the bottom of the image, the button I currently press is the one at the top that occupies the position of the screen itself when one hasn't scrolled yet. In short, not the button at the bottom is clicked when I scroll down and click on it, but the one at the top. How do I solve this? Note: my code is in Swift, so please write down code snippets in Swift and not Objective-C.
func makeImage(){
//might change the following to make it more dynamic later on
imageView = UIImageView(image: UIImage(named:brand.name + "-" + genderChoice.name + "-"+generalOverviewChoice.name+"-Detail.png"))
scrollView = UIScrollView(frame: view.bounds)
scrollView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
imageView.frame = CGRectMake(0, 0, 375, imageView.frame.size.height/2)
scrollView.contentSize = CGSizeMake(375,imageView.frame.size.height)
scrollView.addSubview(imageView)
view.addSubview(scrollView)
}
func createButton(button: UIButton,x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat){
button.frame = CGRectMake(x, y, width, height)
button.addTarget(self, action: "btnTouched:", forControlEvents:.TouchUpInside)
self.view.addSubview(button)
}

Related

UIButton position to bottom right corner of textView in swift

I have a custom class UIView in which i have a textView. And I'm trying to add UIButton to bottom right corner of textView programmatically using autoresizingMask.This is my code:
public init() {
textViewButton = UIButton(type: .custom)
textViewButton.addTarget(self, action: #selector(didPressButton), for: .touchUpInside)
textViewButton.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin, .flexibleLeftMargin]
self.addSubview(textViewButton)
textViewButton.isHidden = true
}
And I'm setting frame in layoutSubviews:
override public func layoutSubviews() {
super.layoutSubviews()
textViewButton.frame = CGRect(x: bounds.maxX - 50, y: 0, width: 50, height: 50)
}
This is the current position of the button with my code:
This is the current position with empty text
This is the current position with my code
How do I fix the button to bottom right corner of textView?

adjustsFontSizeToFitWidth not working with iOS 15 UIButton

I want to size the text on my button to automatically fit to the edges of the button.
This code was working pre-iOS15, now it doesn't.
testButton.titleLabel?.adjustsFontSizeToFitWidth = true
testButton.titleLabel?.minimumScaleFactor = 0.1
How can I automatically resize the text to fit the size of my button in iOS 15?
This is playground code for testing. It includes everything I've tried, but still isn't working.
import UIKit
import PlaygroundSupport
//building button
let testButton = UIButton(frame: CGRect(x: 100, y: 100, width: 300, height: 300))
testButton.setTitle("test", for: .normal)
//everything I've found in other answers that is supposed to work
var titleLabel = testButton.titleLabel!
titleLabel.font = UIFont.systemFont(ofSize: 300)
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.1
titleLabel.numberOfLines = 1 //also tried 0 instead
titleLabel.lineBreakMode = .byClipping
//configuring button
testButton.configuration = UIButton.Configuration.filled()
//display the button
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
containerView.backgroundColor = .white
PlaygroundPage.current.liveView = containerView
containerView.addSubview(testButton)
Related questions I've already looked at and tried:
Best way to adjust font size with width and height of UILabel
Swift - Adjusting fontSize to fit the width of the layout (programmatically)
How to get .adjustsFontSizeToFitWidth to function properly
How to set font size to fill UILabel height?
Auto change the font size to fit the button in swift
UIButton auto-adjust Button font size Swift
I found out it could be caused by testButton.configuration = UIButton.Configuration.filled(), but I don't know why.

Centering buttons programatically in Swift

I am trying to center Google Sign In and Sign Out buttons programmatically. In order to put both of them in the third quarter. I create 2 views that I wanted to put buttons to their center, in Storyboard.
GIDSignIn.sharedInstance()?.presentingViewController = self
GIDSignIn.sharedInstance().signIn()
let gSignIn = GIDSignInButton(frame: CGRect(x: 0, y: 0, width: loginView.frame.size.width, height: loginView.frame.size.height))
loginView.addSubview(gSignIn)
gSignIn.center = loginView.center
let gSignOut = UIButton(frame: CGRect(x: 0, y: 0, width: signOutView.frame.size.width, height: signOutView.frame.size.height))
gSignOut.backgroundColor = UIColor.white.withAlphaComponent(0)
gSignOut.setTitle("Sign Out", for: .normal)
gSignOut.setTitleColor(UIColor.red, for: .normal)
gSignOut.addTarget(self, action: #selector(self.signOut(_:)), for: .touchUpInside)
gSignOut.center = signOutView.center
self.signOutView.addSubview(gSignOut)
As you can see, also I am trying to resize buttons according to view size which helps me to resize buttons depend on device size.
Here is the second half of my storyboard.
Here is the simulator screen when I run the code.
Thanks.
Use auto-layout instead of setting frame.center, it will be more flexible.
Autolayout goes like below code.
GIDSignIn.sharedInstance()?.presentingViewController = self
GIDSignIn.sharedInstance().signIn()
let gSignIn = GIDSignInButton(frame: CGRect(x: 0, y: 0, width: loginView.frame.size.width, height: loginView.frame.size.height))
gSignIn.translatesautoresizingmaskintoconstraints = false
loginView.addSubview(gSignIn)
NSLayoutConstraint.activate([
gSignIn.leftAnchor.constraint(equalTo: loginView.leftAnchor),
gSignIn.rightAnchor.constraint(equalTo: loginView.rightAnchor),
gSignIn.topAnchor.constraint(equalTo: loginView.topAnchor),
gSignIn.bottomAnchor.constraint(equalTo: loginView.bottomAnchor)
])

Align Drop Down Menu Title to prevent overlapping of other buttons

I have the below image where the title of the drop down menu title is overlapped with other buttons. How to solve this issue?
Code:
func createDropDownMenu() {
// create the drop down menu
let title = prepareNavigationBarMenuTitleView()
prepareNavigationBarMenu(title)
updateMenuContentOffsets()
}
func prepareNavigationBarMenuTitleView() -> String {
// Both title label and image view are fixed horizontally inside title
// view, UIKit is responsible to center title view in the navigation bar.
// We want to ensure the space between title and image remains constant,
// even when title view is moved to remain centered (but never resized).
titleView = DropDownTitleView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
titleView.addTarget(self,
action: #selector(DocumentViewController.willToggleNavigationBarMenu(_:)),
for: .touchUpInside)
titleView.addTarget(self,
action: #selector(DocumentViewController.didToggleNavigationBarMenu(_:)),
for: .valueChanged)
titleView.titleLabel.lineBreakMode = NSLineBreakMode.byClipping
titleView.titleLabel.numberOfLines = 2
titleView.titleLabel.textColor = UIColor.black
titleView.title = currentNode.title
navigationItem.titleView = titleView
return titleView.title!
}
I had to set the frame of the TitleLable and set the numberOfLines = 0 to solve my problem.
Code:
titleView.titleLabel.frame = CGRect(x: 0, y: 0, width: 600, height: 80)
titleView.numberOfLines = 0
titleView.titleLabel.text = currentNode.title

Sliding a UIView "Out of nowhere"

i am trying to create a custom dropdown menu. I will have several cards on my view which should have a dropdown menu when tapped.
Right now i am having the dropDownView having cardView.frame.maxY as its frame.origin.y value with a height of 0 and when I tap the card view I set the height of the dropDownView to its real height-value within an animation.
But that looks kind of ugly since it looks like it stretches out of nowhere. I want it to slide out of nowhere.
By that i mean it having its original size right away and sitting below the card view (cardView.frame.maxY = dropDownView.frame.maxY) When the cardView is tapped the dropDownView slides down (dropDownView.frame.origin.y = cardView.frame.maxY) within an animation.
The Problem is, that the dropDownView is bigger than the cardView. So when it sits behind the cardView it is visible above the cardView. I tried to illustrate the Problem :)
This is state A (Before View A[cardView] is tapped) (View C is just some Background View which should be visible above and below View A)
This is state B (after cardView is tapped)
Any Ideas how to solve this problem? Thank you!
In addition heres a little sample code:
class cardViewComplete: UIView {
var card: CardView!
var dropDownMenu: DropDownView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
func initSubViews() {
self.clipsToBounds = true
card = CardView()
card.frame = self.bounds
card.addTarget(self, action: #selector(YellowTackleTicketComplete.ticketTapped), forControlEvents: .TouchDown)
dropDownMenu = DropDownView()
dropDownMenu.frame = CGRect(x: 0, y: self.bounds.maxY, width: self.bounds.width, height: 350)
dropDownMenu.hidden = true
dropDownMenu.backgroundColor = UIColor.clearColor()
self.addSubview(card)
self.insertSubview(dropDownMenu, belowSubview: card)
dropDownMenu)
}
func showDropdown() {
dropDownMenu.hidden = false
originalHeight = self.frame.size.height
print("showing")
if !animating {
animating = true
UIView.animateWithDuration(
0.7,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: [],
animations: {
self.frame.size.height = self.frame.size.height + 350
}, completion: { _ in
self.animating = false
}
)
}
self.setNeedsDisplay()
self.dropDownMenu!.setNeedsDisplay()
dropped = true
}
func ticketTapped() {
showDropdown()
}
}
What I would do is place both View A and View B inside a new view, we can call this containerView.
containerView should be big enough to hold both A and B (when B is moved down). Then set containerView to clip at bounds. So when View B is in the "up" position, it is sitting both behind View A, and clipped at the top of containerView. Therefore it is not seen at all.
Once you're ready for View B to drop to it's "down" position, just animate it going down, where it will appear to come out from the bottom of View A. Since the containerView's frame will extend far enough down to accommodate A and B (in it's down position), nothing will be clipped and both views will be visible.
card = CardView()
card.frame = self.bounds
card.addTarget(self, action: #selector(YellowTackleTicketComplete.ticketTapped), forControlEvents: .TouchDown)
dropDownMenu = DropDownView()
// I changed the frame to place it right underneath the card view
dropDownMenu.frame = CGRect(x: 0, y: card.frame.size.height - 350, width: self.bounds.width, height: 350)
dropDownMenu.hidden = true
dropDownMenu.backgroundColor = UIColor.clearColor()
let containerView = UIView()
containerView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: card.frame.size.height + dropDownMenu.frame.size.height)
containerView.backgroundColor = nil
containerView.clipsAtBounds = true
containerView.addSubview(dropDownMenu)
containerView.addSubview(card)