UIFontPickerViewController black screen in ios17

UIFontPickerViewController open the window cannot show, before ios17 is workable.

Answered by atensadc in 767473022

Flutter and swift code

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const platform = MethodChannel('FontsChannel');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _getFonts();
        },
        tooltip: 'Open',
        child: Icon(Icons.add),
      ),
    );
  }


  Future<void> _getFonts() async {
    await platform.invokeMethod('getBatteryLevel');
  }
}

AppDelegate.swift

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    print("Register")
  
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let fontsChannel = FlutterMethodChannel(name: "FontsChannel",
                                              binaryMessenger: controller.binaryMessenger)
    GeneratedPluginRegistrant.register(with: self)

    fontsChannel.setMethodCallHandler({
      [weak self] (call: FlutterMethodCall, result: @escaping  FlutterResult) -> Void in
      // This method is invoked on the UI thread.
      print("fontsChannel.setMethodCallHandler test")
      if #available(iOS 13.0, *) {
          print("create CustomFont")
          let customFont = CustomFont() // Your viewController
          let navigationController = UINavigationController(rootViewController: customFont)
          self!.window!.rootViewController = navigationController
          self!.window!.makeKeyAndVisible()
          customFont.showFontPicker(window: self!.window, flutterController: controller, flutterCallback: {(font)-> Void in result(font)})
        }
    })

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

CustomFont.swift

import UIKit
import Flutter


@available(iOS 13.0, *)
class CustomFont: UIViewController, UIFontPickerViewControllerDelegate {
  var outsideWindow = UIWindow();
  var outsideController = UIViewController()
  var callback: ((_ font: Dictionary<String, String>) -> Void)?

  @available(iOS 13.0, *)
  @objc func showFontPicker( window: UIWindow, flutterController: UIViewController,
    flutterCallback: ((_ font: Dictionary<String, String>) -> Void)?) {
        let fontConfig = UIFontPickerViewController.Configuration()
        fontConfig.includeFaces = true
        fontConfig.displayUsingSystemFont = false
        fontConfig.includeFaces = false;
        let fontPicker = UIFontPickerViewController(configuration: fontConfig)
        fontPicker = UIFontPickerViewController(configuration: fontConfig)
        fontPicker!.delegate = self
        fontPicker!.modalPresentationStyle = .fullScreen
        outsideWindow = window
        outsideController = flutterController
        callback = flutterCallback

        self.present(fontPicker!, animated: true, completion: nil)
        NSLog("showFontPicker...")
    }

    func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
        // attempt to read the selected font descriptor, but exit quietly if that fails
      print("fontPickerViewControllerDidPickFont")
      guard let descriptor = viewController.selectedFontDescriptor else { return }
        
      outsideWindow.rootViewController = outsideController
      let customFont = UIFont(descriptor:descriptor, size: 36)
      print(customFont.fontName)
      print(customFont.familyName)
      print(customFont.fontDescriptor)

      if(descriptor.fontAttributes[.family] != nil){
        let resultFont = ["font":descriptor.fontAttributes[.family] as! String]
        callback?(resultFont)
      } else{
        let resultFont = ["font":customFont.familyName]
        callback?(resultFont)
      }
      print(descriptor)
      print(descriptor.fontAttributes)
    }
  
    func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
        // handle cancel event here
      NSLog("fontPickerViewControllerDidCancel")
      outsideWindow.rootViewController = outsideController
    }
}
Accepted Answer

Flutter and swift code

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const platform = MethodChannel('FontsChannel');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _getFonts();
        },
        tooltip: 'Open',
        child: Icon(Icons.add),
      ),
    );
  }


  Future<void> _getFonts() async {
    await platform.invokeMethod('getBatteryLevel');
  }
}

AppDelegate.swift

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    print("Register")
  
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let fontsChannel = FlutterMethodChannel(name: "FontsChannel",
                                              binaryMessenger: controller.binaryMessenger)
    GeneratedPluginRegistrant.register(with: self)

    fontsChannel.setMethodCallHandler({
      [weak self] (call: FlutterMethodCall, result: @escaping  FlutterResult) -> Void in
      // This method is invoked on the UI thread.
      print("fontsChannel.setMethodCallHandler test")
      if #available(iOS 13.0, *) {
          print("create CustomFont")
          let customFont = CustomFont() // Your viewController
          let navigationController = UINavigationController(rootViewController: customFont)
          self!.window!.rootViewController = navigationController
          self!.window!.makeKeyAndVisible()
          customFont.showFontPicker(window: self!.window, flutterController: controller, flutterCallback: {(font)-> Void in result(font)})
        }
    })

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

CustomFont.swift

import UIKit
import Flutter


@available(iOS 13.0, *)
class CustomFont: UIViewController, UIFontPickerViewControllerDelegate {
  var outsideWindow = UIWindow();
  var outsideController = UIViewController()
  var callback: ((_ font: Dictionary<String, String>) -> Void)?

  @available(iOS 13.0, *)
  @objc func showFontPicker( window: UIWindow, flutterController: UIViewController,
    flutterCallback: ((_ font: Dictionary<String, String>) -> Void)?) {
        let fontConfig = UIFontPickerViewController.Configuration()
        fontConfig.includeFaces = true
        fontConfig.displayUsingSystemFont = false
        fontConfig.includeFaces = false;
        let fontPicker = UIFontPickerViewController(configuration: fontConfig)
        fontPicker = UIFontPickerViewController(configuration: fontConfig)
        fontPicker!.delegate = self
        fontPicker!.modalPresentationStyle = .fullScreen
        outsideWindow = window
        outsideController = flutterController
        callback = flutterCallback

        self.present(fontPicker!, animated: true, completion: nil)
        NSLog("showFontPicker...")
    }

    func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
        // attempt to read the selected font descriptor, but exit quietly if that fails
      print("fontPickerViewControllerDidPickFont")
      guard let descriptor = viewController.selectedFontDescriptor else { return }
        
      outsideWindow.rootViewController = outsideController
      let customFont = UIFont(descriptor:descriptor, size: 36)
      print(customFont.fontName)
      print(customFont.familyName)
      print(customFont.fontDescriptor)

      if(descriptor.fontAttributes[.family] != nil){
        let resultFont = ["font":descriptor.fontAttributes[.family] as! String]
        callback?(resultFont)
      } else{
        let resultFont = ["font":customFont.familyName]
        callback?(resultFont)
      }
      print(descriptor)
      print(descriptor.fontAttributes)
    }
  
    func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
        // handle cancel event here
      NSLog("fontPickerViewControllerDidCancel")
      outsideWindow.rootViewController = outsideController
    }
}
UIFontPickerViewController black screen in ios17
 
 
Q