material-components-ios icon indicating copy to clipboard operation
material-components-ios copied to clipboard

[TextControls] MDCBaseTextField at density 1 not as dense as Android with .Dense styles

Open arevellfraedom opened this issue 4 years ago β€’ 28 comments

A clear and concise description of what the bug is.

Reproduction steps

Steps to reproduce the behavior:

  1. Create an class inheriting from MDCBaseTextField
  2. Create a new implementation of the createPositioningReference method to return a MDCTextControlVerticalPositioningReference with density of 1, rather than 0 as per MDCTextFieldOutlinedDense.zip
  3. Observe that the total height between outlines is approx 53pt with vertical padding between text and outlines of about 12 pt as per MDCBaseTextField at density 1
  4. Create an android layout with a TextInputLayout with style Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense such as DenseTextInput.zip
  5. 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 Screenshot_1583720382

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

arevellfraedom avatar Mar 09 '20 02:03 arevellfraedom

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

Simulator Screen Shot - iPhone 11 Pro Max - 2020-03-09 at 10 46 54

andrewoverton avatar Mar 09 '20 14:03 andrewoverton

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 avatar Mar 09 '20 16:03 arevellfraedom

@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.

andrewoverton avatar Mar 09 '20 20:03 andrewoverton

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 πŸ˜„)

andrewoverton avatar Mar 09 '20 20:03 andrewoverton

I vote for number 3 understanding this one as the possibility to customize desired density

Fernandez-Aldo avatar Mar 09 '20 21:03 Fernandez-Aldo

@Fernandez-Aldo your vote will only be counted if you put a πŸŽ‰ reaction on the comment! Only half kidding

andrewoverton avatar Mar 09 '20 21:03 andrewoverton

Done!! Please count it!!! hahaha

Fernandez-Aldo avatar Mar 09 '20 21:03 Fernandez-Aldo

@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

joshuangfraedom avatar Mar 09 '20 22:03 joshuangfraedom

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

arevellfraedom avatar Mar 09 '20 22:03 arevellfraedom

I switched to another library because setting the MDCOutlinedTextField height feature is missing

vidalbenjoe avatar Jun 21 '20 14:06 vidalbenjoe

Hi @vidalbenjoe, out of curiosity, which library did you switch to?

andrewoverton avatar Jun 22 '20 22:06 andrewoverton

@vidalbenjoe Could you please name the library. Even I am facing the same issue.

hardikamal avatar Jul 18 '20 14:07 hardikamal

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.

feipe56 avatar Sep 04 '20 22:09 feipe56

hi, any updates on this feature or estimated release date?

jpujolji avatar Jan 20 '21 15:01 jpujolji

@jpujolji no update until now. haha

vidalbenjoe avatar Jan 21 '21 15:01 vidalbenjoe

@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.

razor313 avatar Feb 02 '21 08:02 razor313

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 avatar Feb 03 '21 04:02 andrewoverton

@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!. 😁

razor313 avatar Feb 03 '21 07:02 razor313

How do we use veriticalDensity on MDCTextInputControllerOutlined?

Fernandez-Aldo avatar Apr 02 '21 17:04 Fernandez-Aldo

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.

andrewoverton avatar Apr 02 '21 21:04 andrewoverton

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?

Fernandez-Aldo avatar Apr 06 '21 17:04 Fernandez-Aldo

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.

andrewoverton avatar Apr 06 '21 19:04 andrewoverton

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

Fernandez-Aldo avatar Apr 06 '21 20:04 Fernandez-Aldo

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.

andrewoverton avatar Apr 06 '21 20:04 andrewoverton

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?

Fernandez-Aldo avatar Apr 06 '21 21:04 Fernandez-Aldo

@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?

Fernandez-Aldo avatar Apr 13 '21 21:04 Fernandez-Aldo

These docs should help you get started.

andrewoverton avatar Apr 15 '21 15:04 andrewoverton