material-components-ios
material-components-ios copied to clipboard
[TextControls] MDCBaseTextField at density 1 not as dense as Android with .Dense styles
A clear and concise description of what the bug is.
Reproduction steps
Steps to reproduce the behavior:
- Create an class inheriting from MDCBaseTextField
- Create a new implementation of the createPositioningReference method to return a MDCTextControlVerticalPositioningReference with density of 1, rather than 0 as per MDCTextFieldOutlinedDense.zip
- Observe that the total height between outlines is approx 53pt with vertical padding between text and outlines of about 12 pt as per
- Create an android layout with a TextInputLayout with style Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense such as DenseTextInput.zip
- Observe that the total height from top and bottom outlines is approx 40dp with vertical adding between text and outlines of about 6 dp as per
Expected behavior
I would expect the highest density of 1 to result in a vertical height and therefore padding very nearly the same as Android.
Actual behavior
At the highest density of 1 the iOS control is noticeably higher (via vertical padding) than the equivalent in Android.
Platform (please complete the following information)
- iPhone 11 Prox Max simulator
- OS: 13.2.2
The title doesn't have a [Component] prefix.
Hi @arevellfraedom, just out of curiosity, are you subclassing MDCBaseTextField and adding your own outline behavior? MDCBaseTextField is not intended to be subclassed--subclassing is not supported. Unfortunately, until https://github.com/material-components/material-components-ios/pull/9861 was merged, the docs did not indicate that haha π
Regarding your density issue, we haven't exposed density yet, but a lot of people seem to want it, so I'm thinking we really should. When we do expose it, I'm not opposed to changing the "min" values in the positioning references (either filled or outlined) to make them more dense. What do you think of this screenshot? This is what you get with the changes here: https://github.com/material-components/material-components-ios/compare/develop...andrewoverton:density?expand=1
Hi and thanks for your response @andrewoverton. I certainly have no great desire to subclass - that was purely to get at the density given the classes involved supported it but set to 0 for outlined. So if there was an alternative way to say βDenseβ that was equivalent to Android (which literally just allows two states - Dense and not) then I would have no desire to subclass.
Your screenshot looks good - probably still not as dense as Android by maybe a pixel or two, but this would be more than acceptable for what I want to use it for. Although it looks like it has thrown off the centering of the clear button!
All in all your proposal looks good and I think is a very handy application of density to this control.
@arevellfraedom, interesting! When I built the mechanism for density in these text fields I envisioned it as being a gradual thing. I figured the user should be able to decide how dense they want the text field. Is that not really useful to you?
And yeah, I noticed that about the clear button :/ Right now it's told to be centered with the text for both the filled and outlined styles. It's possible it's supposed to be centered within the container--the outline in this case.
As a user, how would you want to configure density? In other words, what would your preferred density API be? Vote with the GitHub emoji react thingy. Voting more than once is permitted.
- The text field should have a property of enum type
MDCTextControlDensity
, with two possible cases,.normal
and.dense
. (vote with π) - The text field should have a BOOL
isDense
property. (vote with π) - The text field should expose a CGFloat
verticalDensity
property that can have any value from 0 to 1, inclusive, where 0 is least dense and 1 is most dense. This option allows the user to experiment with various levels of density. (vote with π) - A bunch of CGFloat properties for all the different vertical distances between the various subviews (vote with π)
I vote for number 3 understanding this one as the possibility to customize desired density
@Fernandez-Aldo your vote will only be counted if you put a π reaction on the comment! Only half kidding
Done!! Please count it!!! hahaha
@arevellfraedom I interpret that material design document differently. To me the guidelines show Normal, Compact and Comfortable in the context of an example demonstrating how density is consistent across controls.
On android we have style inheritance etc which allows for globally setting control defaults, but you can always override them. iOS lacks this kind of styling and instead we will need to define the controls as dense, etc. at the time the control is created, in code, and then also provide a way to override them later on (this is to achieve parity with Android's material controls).
To do this in a more universal way (to provide consistency), these controls would need something like a factory, which is initialized with a density mode, and configures the controls before returning them, this can be done (I think) outside of this library.
I do agree with you in a way, i think that controls should be able to take an enum as a constructor arg that allows them to be styled with a preset default (π), but I also think that the control should expose the ability to override these defaults so that it can be customized however way we wish (π).
ΒΏPor quΓ© no los dos?
As an aside, I would specifically recommend against a BOOL value as it is the least flexible for defining something that may end up being added too with other scales. And the density float (π) would be an either or vs π, but I prefer finer control
I deleted my comment after talking to @joshuangfraedom. I now vote π as the primary option but if it can be combined with π so somehow give the ease of a default but overridable, that would be extra good.
Also, in addition, we found with the density increased on Android it looked better when the left padding was also reduced. Which is similar here between the "F" and the purple line
I switched to another library because setting the MDCOutlinedTextField height feature is missing
Hi @vidalbenjoe, out of curiosity, which library did you switch to?
@vidalbenjoe Could you please name the library. Even I am facing the same issue.
I vote for number 3, please.. when this release will available?
I need this for my project, because the text fields they are very large for my layout and that leaves ugly.
hi, any updates on this feature or estimated release date?
@jpujolji no update until now. haha
@andrewoverton Could you please tell me, how long we should wait for it? As @feipe56 mentioned before we need it extremely since the text fields are very ugly.
Hi everyone, thank you for patience. https://github.com/material-components/material-components-ios/commit/73e404888d1e98e930e62b68f864b60e264c32f3, which exposes verticalDensity
, landed in develop earlier. It'll be in next week's release. It also includes some tweaks to the constants that will hopefully make the text fields dense enough for most of you. Let me know if you want them denser! @razor313 , hopefully you find them a little less "ugly" now! π
@andrewoverton Good job, thank you very much!!!. I'll be waiting for it until the next release week. I'm very enthusiastic to see it on my project!. π
How do we use veriticalDensity on MDCTextInputControllerOutlined?
Hi @Fernandez-Aldo , verticalDensity
is a property on MDCBaseTextField
, which is the superclass of MDCOutlinedTextField
. MDCTextInputControllerOutlined
is part of the old text field implementation, which doesn't support variable densities.
Hello @andrewoverton can you point me to an updated guide on how to use this new TextFields? I'm interested in customizing MDCOutlinedTexfields. Also, is there a difference between this and MDCOutlinedTextArea?
Hi @Fernandez-Aldo, what are you interested in customizing? MDCBaseTextField is a subclass of UITextField, and MDCBaseTextArea is a subclass of UIControl that contains a UITextView. In other words, the text areas are multi-line instead of single-line.
Hello @andrewoverton I have this kind of customization with the ones I'm currently using:
containerScheme.colorScheme.primaryColor =.someColor containerScheme.colorScheme.errorColor = .someColor emailAddressController = MDCTextInputControllerOutlined(textInput: emailAddress) emailAddressController?.applyTheme(withScheme: containerScheme) emailAddress.leadingUnderlineLabel.numberOfLines = 0 emailAddress.leadingUnderlineLabel.lineBreakMode = NSLineBreakMode(rawValue: 0)! emailAddress.leadingUnderlineLabel.accessibilityIdentifier = "someAccID" viewModel.emailTicImageView.image = viewModel.wrongEmail viewModel.emailTicImageView.setImageColor(color: SomeColor) emailAddress.clearButton.setImage(viewModel.emailTicImageView.image, for: .normal) emailAddress.keyboardType = .emailAddress emailAddress.font = UIFont(name: Fonts.OpenSans_Regular, size: 18 * scaleFactor) emailAddressController?.textInputFont = MDCTypography.subheadFont() emailAddressController?.borderStrokeColor = SomeColor emailAddressController?.inlinePlaceholderColor = SomeColor
Hi @Fernandez-Aldo ,
This is my attempt at adapting your code to the new text fields:
containerScheme.colorScheme.primaryColor =.someColor
containerScheme.colorScheme.errorColor = .someColor
emailAddress.applyTheme(withScheme: containerScheme)
emailAddress.leadingUnderlineLabel.numberOfLines = 0
emailAddress.leadingUnderlineLabel.lineBreakMode = NSLineBreakMode(rawValue: 0)!
viewModel.emailTicImageView.image = viewModel.wrongEmail
viewModel.emailTicImageView.setImageColor(color: SomeColor)
emailAddress.keyboardType = .emailAddress
emailAddress.font = UIFont(name: Fonts.OpenSans_Regular, size: 18 * scaleFactor)
emailAddress.font = MDCTypography.subheadFont()
// "emailAddressController?.borderStrokeColor = SomeColor" becomes the following three lines:
emailAddress.setOutlineColor(SomeColor, forState: .normal)
emailAddress.setOutlineColor(SomeColor, forState: .editing)
emailAddress.setOutlineColor(SomeColor, forState: .disabled)
// "emailAddressController?.inlinePlaceholderColor = SomeColor" becomes this line:
emailAddress.setLabelColor(SomeColor, forState: .normal)
// I think this should work:
emailAddress.leadingAssistiveLabel.accessibilityIdentifier = "someAccID"
The only thing that the new text fields don't have an equivalent for is the clear button:
emailAddress.clearButton.setImage(viewModel.emailTicImageView.image, for: .normal)
The new text fields use the system clear button.
Thanks a lot @andrewoverton I'll give it a try! How do I integrate new texfields to my project? Curently I'm just doing it like this:
@IBOutlet weak var emailAddress: MDCTextField!
var emailAddressController: MDCTextInputControllerOutlined?
let typographyScheme = MDCTypographyScheme()
let containerScheme = MDCContainerScheme()
And in the StoryBoard I'm giving the textfield the MDCTextfield Class
BTW, What about density? Is it just
emailAddress.vertiticalDensity = 0.5?
@andrewoverton me again... How do I integrate new texfields to my project? Curently I'm just doing it like this: @IBOutlet weak var emailAddress: MDCTextField! var emailAddressController: MDCTextInputControllerOutlined? let typographyScheme = MDCTypographyScheme() let containerScheme = MDCContainerScheme()
And in the StoryBoard I'm giving the textfield the MDCTextfield Class BTW, What about density? Is it just emailAddress.vertiticalDensity = 0.5?
These docs should help you get started.