Skip to content
View in the app

A better way to browse. Learn more.

FGX Native

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

1.19.6.0 Русский

Featured Replies

  • Administrators

Скачать:

Дата релиза:
3 июня 2026


Новое

TfgWebBrowser

Добавлены два новых события: OnPermissonRequest и OnConsoleMessage.

Добавлен новый демонстрационный проект: "Компоненты" -> "TfgWebBrowser" -> "Запрос разрешений"

Работа с разрешениями

Событие OnPermissonRequest позволяет управлять доступом веб-браузера к камере, микрофону и приватным медиа данным. Событие вызывается в тот момент, когда загружаемый контент в браузере хочет получить приватный доступ к камере, микрофону или другим ресурсам. На вход события передается набор запрашиваемых ресурсов AResources:

TfgPermissionResource = (AudioCapture, VideoCapture, ProtectedMedia);
TfgPermissionResources = set of TfgPermissionResource;

TfgPermissionRequestEvent = procedure(Sender: TObject; const AUrl: string; const AResources: TfgPermissionResources;
                                      const AHandler: IFGXPermissionRequestHandler) of object;

AHandler используется для подтверждения или отклонения такого доступа. Вам необходимо в этом событие сделать такой запрос системе, и по получении подтверждения от пользователя сообщить браузеру, что доступ разрешен посредством вызова AHandler.Grant(Resources). Если же никакой доступ не выдан - AHandler.Deny.

Обратите внимание, что системные разрешения запрашиваемые через TfgPermissionService.RequestPermissionsAsync выдаются на все ваше приложение. А это значит, что любой компонент и код в рамках вашего приложения автоматически получает доступ. Однако, веб-браузер позволяет подгружать любой контент динамически. И чтобы контент веб браузера не мог следить за пользователем (при условии ранее выданного доступа), он автоматически запрашивает такое разрешение доступа у разработчика через новое событие. Если же разработчик не выдает такой доступ или же не пишет обработчик, такой запрос доступа автоматически считается отклоненным.

Также, это событие НЕ запрашивает доступ к камере или микрофону у системы, а лишь позволяет вам заблокировать такой доступ. Если вы одобрите этот доступ в этом событие, но не получите разрешение у системы, то браузер не сможет использовать камеру и микрофон.

Данное событие актуально только для платформы Андроид. По сколько iOS автоматически запрашивает такой доступ у пользователя автоматически.

Консоль

Событие OnConsoleMessage позволяет перехватить сообщение, выводимое Javascript в консоль веб-браузера. Работает только на Андроид.

Улучшения 🙌

TfgCollectionView

В этом релизе изменен подход к динамическому расчету размеров элементов TfgCollectionView. Несмотря на то, что список допускал изменение высот (для вертикально ориентированного списка) элементов, предложенное нами решение не являлось до конца согласованным с тем, как работает список в iOS.

Как вы знаете, отображение элементов в TfgCollectionView не зависит от их количества. Потому что всегда отображаются только видимые элементы. Несмотря на то, что принцип работы списка схож в Android и iOS, разница все же есть:

  1. В Андроиде вы никогда не узнаете суммарный размер элементов списка (он же ContentSize) и точное смещение содержимого ContentOffset. Чтобы узнать точное смещение списка и размер содержимого, ему пришлось бы вначале загрузить все элементы, чтобы узнать у каждого элемента его реальную высоту. Но для скорости работы в Андроиде это не делается. Поэтому расчет смещения выполняется по среднему значению высот элементов в видимом окне (используется алгоритм скользящего окна). И значит в Андроиде можно безнаказанно менять размер элемента в любой момент времени, потому что это не влияет на расчет смещения и размер содержимого в парадигме работы компонента под Android.

  2. В iOS же ситуация полностью противоположная, список первым делом запрашивает размеры у всех элементов и только потом их выводит. Поэтому любое изменение размера элементов уже после того, как список запросил все размеры и провел все тяжелые вычисления, приводит к очень сложной актуализации внутреннего состояния списка с дальнейшими проблемами в скорости работы. Начиная с iOS 26 любая такая попытка изменения размера заканчивается падением приложения, потому что нативная реализация списка это не учитывает.

Поэтому нам пришлось переосмыслить подход к динамическому расчету высот элементов:

  1. Если вы планируете менять высоту элементов динамически, то теперь необходимо явно об этом указать списку, установив значение нового свойства TfgCollectionViewStyle.VariableSize = True. По умолчанию, значение равно False. Если этого не сделать, то установленный размер элементов в OnBindItem будет проигнорирован и будет использован размер стиля, взятый из дизайнера.

  2. Как и ранее, расчет высоты элементов необходимо осуществлять в TfgCollectionView.OnBindItem. Указанная высота кешируется в списке и используется для ускорения работы списка. При изменении размера списка, а также при вызове ReloadItems и других аналогичных методов, кеш автоматически сбрасывается и вам будет предложено повторно пересчитать размеры элементов в TfgCollectionView.OnBindItem.

  3. Если по каким-то причинам, вы хотите пересчитать размер элемента, то вам необходимо сообщить списку об этом по средством вызова методов ReloadItems, ReloadItem. Если этого не сделать, то любая попытка задать новый размер, который будет отличаться от первоначального, будет проигнорирована списком.

Рассмотрим пример. У нас есть простой список с элементами, отображаемыми надпись при помощи единственного компонента стиля TfgLabel (text).

Тогда вспомогательный метод, выполняющий расчет высоты метки при фиксированной ширине может выглядеть так:

procedure TFormMain.AdjustHeight(const AItem: TfgItemWrapper);
begin
  var LLabel := AItem.GetControlByLookupName<TfgLabel>('text');
  if LLabel = nil then
    Exit;

  var Item := AItem.Item;
  // Выполняем расчет доступной ширины метки для вывода текста с учетом внешних и внутренних отступов
  var TotalHItemPadding := Item.Padding.LeftRtl + Item.Padding.RightRtl;
  var TotalHLabelMargins := LLabel.Margins.LeftRtl + LLabel.Margins.RightRtl;
  var TotalVLabelMargins := LLabel.Margins.Top + LLabel.Margins.Bottom;
  var ContentWidth := Item.Width - TotalHItemPadding - TotalHLabelMargins;

  // Выполняем расчет размера метки для отображения текста с учетом фиксированной ширины.
  var Sz := LLabel.MeasureSize(TfgMeasuringSpecification.Fixed, ContentWidth, TfgMeasuringSpecification.Unspecified, 0);
  
  Item.Height := Sz.Height + TotalVLabelMargins;
end;

Тогда связывание элементов с данными и задание размера будет выглядеть так:

procedure TFormMain.cvListBindItem(Sender: TObject; const AIndex: Integer; const AStyle: string;
  const AItem: TfgItemWrapper);
var
  ItemText: string;
begin
  ItemText := FItems[AIndex];
  var LLabel := AItem.GetControlByLookupName<TfgLabel>('text');
  if LLabel <> nil then
    LLabel.Text := ItemText;
  AdjustHeight(AItem);
end;

Так же не забываем, что для стиля нужно указать TfgCollectionViewStyle.VariableSize = True.

TfgNavigationBar

Расширены настройки отображения иконки кнопок ActionButtons. Для кнопки TfgNavigationBarButton введено новой свойство Icon, отвечающее за настройку отображения иконки на кнопке. Теперь доступны следующие настройки:

  • RenderMode - отвечает за нужно ли перекрашивать иконку в заданный оттенок или выводить иконку, как она есть.

  • TintColor/TintColorName - цвет оттенка иконки. Позволяет переопределить оттенок иконки, заданный через свойство TfgNavigationBar.ButtonsOptions.IconTintColor/IconTintColorName по умолчанию.

TfgLabel

  • Унифицирован парсер HTML TfgLabel для всех платформ.

  • Для режима TfgLabel.TextType = TfgTextType.HTML добавлено отображение текста дизайнере.

  • Добавлен многострочный редактор текста TfgLabel.Text при редактировании в инспекторе объектов.

Исправление ошибок 🐛

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.