Еквівалент iOS для Android View. GONE режим видимості


79

Я розробляю додаток для iOS і використовую Раскадровку з увімкненим AutoLayout. Один з моїх контролерів перегляду має набір з 4 кнопок, і за певних обставин я хотів би змусити перший зникнути.

Якщо я використовую setHidden:TRUEметод, кнопка UIB стає невидимою, але вона все одно, очевидно, займає місце у поданні, і в результаті виходить "діра", яку я не зміг заповнити, змусивши залишитися кнопку UIB плавати у верхній частині головного виду.

В Android я б просто використовував View.GONEзамість цього View.INVISIBLE, але в iOS я застряг у цій поведінці, і я не хочу вірити, що єдиним рішенням є ручне (так, я маю на увазі програмне) переміщення решти елементів вгору.

Я думав, що зміг би це зробити, встановивши якийсь Обмеження, щоб зробити все настільки ж автоматичним, як в Android, але мені не пощастило.

Перш ніж я ВИМКНУТИ авторозкладку, хтось може вказати мені правильний напрямок?

Я використовую IB, але мене також влаштовують програмні речі.

ОНОВЛЕННЯ:

Встановлення висоти компонента на 0 також не допомагає.

Я спробував щось подібне:

UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;

Як щодо встановлення висоти кнопки на нуль?
cahn

Я спробував щось подібне: UIButton * b; CGRect frameRect = b.frame; frameRect.size.height = 0; b.frame = frameRect; Не пощастило :(
elbuild

Я знаю, що це надзвичайно старе питання, але щодо вашого оновлення, встановивши фрейм на 0, не допоможе, якщо ви використовуєте авторозкладку. Ви повинні встановити обмеження висоти на 0
wyu

Відповіді:


40

Додавання обмеження (NSLayoutAttributeHeight), яке встановлює висоту подання до 0, спрацювало для мене:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];

11
Свіфт версія:self.view.addConstraint(NSLayoutConstraint(item: self.captchaView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0))
iStar

1
Це мала бути відповідь
Рік Ройд Абан

2
Що робити, якщо я не знаю фактичної висоти бажаного подання (наприклад, вигляд контейнера, наданий трохи згодом)?
А. Петров

Велике спасибі за чудову відповідь! Для когось це може знадобитися. Помилка Unable to simultaneously satisfy constraints. в той час як я вже мав обмеження для зору. Я вирішую це за допомогою stackoverflow.com/a/38625419/1270901
Nevin Chen

@iStar я використовував той же код , але він не працює ... stackoverflow.com/questions/45454992 / ...
Санджай Mangaroliya

20

Всі відповіді на ці питання неефективні. Найкращий спосіб еквівалентності Android setVisibility: Метод Gone на iOS полягає в тому, що StackViewспочатку виберіть компоненти, а потім у редакторі, вбудуйте в, Stack View,

підключіть новий вигляд стека до IBOutlet, а потім:

прихований:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = YES;

видимість:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = NO;

оскільки при використанні подання стека, всі обмеження будуть збережені!

Документ


Насправді це здається справді хорошим рішенням, але варто зазначити, що йому потрібен iOS9 +.
user3533716

Я скористався вашим блискучим рішенням (+1 для вас, дякую !!), але я підключився через IBOutlet безпосередньо до подання, яке я хотів показати та приховати, тож я повинен ввести лише один рядок коду! :)
Cristina De Rito

1
Ця відповідь насправді не правильна. Android View.GONE видаляє перегляд інтерфейсу користувача. Наприклад, якщо ви встановите для елемента View.GONE елемент, подання нижче цього місця змістяться вгору. Отже, ваша пропозиція просто приховує вигляд, рівний View.HIDE. Подивіться на цю відповідь: stackoverflow.com/questions/11556607/…
emin deniz

Я не шукав на android api ... Але я розробник мобільних пристроїв, тому знаю механіка ... В Android з булевим видом прапора можна переглядати чи ні (Gone, Visible) Якщо його буде видалено з інтерфейсу користувача, буде важко додати ще раз ... але в ios, це в макеті, але без пробілів .... Більше того, є офіційно приховане властивість ios, яке має місце ... UIStackview приховане властивість, як android View.Gone
Ucdemir

16

додайте обмеження висоти до вашого подання наступним чином:введіть тут опис зображення

потім зробіть вихід для обмеження висоти у файлі viewController наступним чином:введіть тут опис зображення

а потім у методі viewDidLoad змініть висоту обмеження на 0 наступним чином:

override func viewDidLoad() {
    super.viewDidLoad()
nsLcButtonHeight.constant = 0
}

1
постійна висота відстій, я використовую однакову висоту і множник, наприклад, щоб взяти 25% батьківського перегляду, будь-який приклад для цього?
user924

8

Щоб досягти Androids.GONE функціональність на iOS - це використовувати UIStackView. Після цього сховайте дитину за позицією. ( Документація щодо яблук )

SWIFT 4:

let firstView = cell.rootStackView.arrangedSubviews[0]
    firstView.isHidden = true // first view gone

Це приклад комірки таблиці, просто вставте обидві внутрішні частини Stack viewта отримайте предмет для GONEдитини.

введіть тут опис зображення


6

Що ви можете зробити, це згрупувати свої подання під поданням стека. Потім, коли ви приховуєте певний вигляд, решта переглядів автоматично зміщуються, щоб заповнити простір.

Можливо, ви захочете ознайомитися з документацією Apple щодо переглядів стеку: https://developer.apple.com/reference/uikit/uistackview

або онлайн-підручники, такі як: https://www.appcoda.com/stack-views-intro/


1

1) Якщо ваші кнопки розташовані вертикально, тоді ви повинні встановити значення height0, а у випадку горизонтально розташованих кнопок спробуйте встановити widthзначення 0 або ви можете встановити обидва значення на 0.

АБО

2) ви можете спробувати такий підхід, який встановлюється button2поверх button1:

- (void)viewDidLoad
{
[super viewDidLoad];

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:@"hello" forState:UIControlStateNormal];

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setTitle:@"world" forState:UIControlStateNormal];

[button1 sizeToFit]; [button2 sizeToFit];
[button2 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];

[self.view addSubview:button1];
[self.view addSubview:button2];

}


1

Це запитання досить давнє, але знайдене мною шафа встановлює додаткові обмеження (тому види навколо подання "пішов" знають, що робити, коли його не буде)

A  which you want to be     A
|  after setting B to gone  |
B                           C
|                               
C                               
  1. Встановіть обмеження нижчого пріоритету (750) від C до A.
  2. Додайте верхнє та нижнє обмеження B (або ліворуч та праворуч, якщо ви хочете, щоб ваш вигляд згортався горизонтально) до масиву NSLayoutConstraint bConstraints. Зробіть це за допомогою:
    1. Клацніть і перетягніть з обмеження на ViewController
    2. Змініть підключення від Outlet до Outlet Collection
    3. Для імені поставте bConstraints.
    4. Натисніть "Підключитися". Це створить @IBOutlet var bConstraints: [NSLayoutConstraint]!у вашому ViewController
    5. Щоб додати додаткові обмеження: перетягніть з обмеження в Storyboard до імені змінної @IBOutlet
  3. Потім сховайте Б

    B.hidden = true
    NSLayoutConstraint.deactivateConstraints(bConstraints)
    
  4. Показати

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    

Очевидно, що чим більше і більше переглядів у вас, тим складніше це зростає, оскільки вам потрібні додаткові обмеження для кожного перегляду


було б корисніше, якби ви пояснили, чому не змогли реалізувати
wyu

Другий момент. Працюю в Ксамаріні. Досі не знайшли рішення цієї проблеми. Не знаю, як слід будувати масив NSLayoutConstraint з обмеженнями B. Я припускаю, що це робиться програмно, було б непогано бачити код для цього. Мені здається, що ваш метод є найбільш розумним способом вирішення цієї проблеми, проте його непросто реалізувати лише псевдокодом
Густаво Байоккі Коста,

Я не використовував Xamarin. Це робиться в XCode: ctrl-клацання та перетягування з обмеження на ViewController (це схоже на те, як ви створили IBOutlet у xcode). У спливаючому вікні (схожому на i.stack.imgur.com/JegLK.png ) змініть спадне меню "Підключення" з OutletнаOutlet Collection . Для додаткових обмежень, ctrl перетягніть безпосередньо до імені змінної. Я можу завантажити знімки зображень пізніше сьогодні (через ~ 8 годин)
wyu,

отже, масив NSLayoutConstraint - це колекція торгових точок, трохи загубилася тут, ха-ха, що ж, не поспішаючи відповісти на мої запитання :)
Густаво Байоккі, Коста,

так, я оновлю відповідь, щоб бути більш зрозумілою. Отже, рішення працює для вас?
wyu

0

Як показали мої дослідження, навіть AutoLayout не може вам допомогти. Вам доведеться вручну замінити подання, на які впливає додатково показаний компонент (у моєму випадку всі подання внизу додаткового подання, але ви впевнені, що ви можете адаптувати це для обробки всіх кнопок праворуч від додаткової кнопки ):

- (IBAction)toggleOptionalView:(id)sender {
    if (!_expanded) {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, _optionalHeight);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = YES;
    } else {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, 0);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = NO;

    }
}

Бажано не жорстко кодувати висоту / ширину додаткових компонентів, інакше ваш код ламається кожного разу, коли ви редагуєте XIB / Storyboard. У мене є поле float _optionalHeight, яке я встановив у viewDidLoad, тому воно завжди оновлене.


0

Ви також можете очистити сторінку або принаймні певні клітинки сторінки та перевизначити все це. Це швидко і працює добре. Я не написав код, але знайшов його в цьому вже існуючому проекті, над яким я працюю. Створюйте ManagementTableSectionі ManagementTableCellкласи для управління цим усім. На жаль, я не можу надати краще визначений код.


0

Спираючись на відповідь, надану Деніз, ось рішення із використанням обмежень у Swift

Наприклад: Якщо у вас є 3 подання, A_view B_view і C_view вертикально вирівняні в такому порядку, і ви хочете "Сховати" B, а також відкоригувати різницю, додайте обмеження

B_view.removeFromSuperView()
var constr = NSLayoutConstraint(item: C_view, 
                                attribute: NSLayoutAttribute.Top, 
                                relatedBy: NSLayoutRelation.Equal, 
                                toItem: A_view, 
                                attribute: NSLayoutAttribute.Bottom,
                                multiplier: 1,
                                constant: 20)
view.addConstraint(constr)

константа - це (у цьому випадку) величина вертикального простору між C_view та A_view


0

Я додав нову властивість до користувацької реалізації UIView під назвою "visible", яка, якщо встановлено значення false, додає обмеження для згортання подання (я додав лише обмеження ширини, оскільки мій список горизонтальний, але найкращим способом може бути додавання обмеження висоти також 0).

var visible:Bool = true{
        didSet{
            if(visible){
                clipsToBounds = false;
                removeConstraint(hideConstraint!)
            }else{
                clipsToBounds = true
                addConstraint(hideConstraint!)
            }
        }
    }

Вам потрібно ініціалізувати обмеження нульової ширини у поданні та додати його як поле:

private var hideConstraint:NSLayoutConstraint?


func someInitFunction(){
    hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
    ...
}

-3

setHidden: TRUE / FALSE - це найближчий еквівалент Android View.GONE / VISIBLE.

Вид не обов'язково займає місце, якщо його не видно!

Я створив ComboBox-Alike із ListView, який кладеться поверх інших видів. Я бачу лише під час вибору:

введіть тут опис зображення


ви забули, що в android у нас також є view.invisible ... view.gone не схожий на setHidden ... його view.invisible, який схожий на setHidden
Nav
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.