我正在尝试创建自己的 Beamer 主题,但在处理标题时遇到了问题。我想为框架标题创建一个带有彩色线条的标题,而对于其他框架,我想要一个带有部分甚至子部分的经典标题。这是我使用的代码部分:
\defbeamertemplate*{headline}
{ \ifnum\c@framenumber>1
\leavevmode%
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=\headerheight,dp=0pt]{}%
\ifx\insertsection\@empty
\else
{
{\usebeamerfont{headsection}\hspace{1em} \color{LightBlue}\insertsection}
\ifx\insertsubsection\@empty
\else
{\hspace{0.5em}$\vert$ \hspace{0.5em}{\usebeamerfont{headsubsection}\color{DarkGray}\insertsubsection}}%
\fi
}
\fi
\end{beamercolorbox}%
} %
\vskip0pt%
\else
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=20pt,dp=0pt]{linemid}
\end{beamercolorbox}%
}
\fi
}
这样,我得到的结果并不令人满意,因为标题框中的彩色线条没有问题,但后续框的部分和子部分(以及标题和框的主体)都向下移动了。似乎 Beamer 为第一个标题保留了空间,但我不想这样。有办法解决这个问题吗?
答案1
没错,beamer
包只在文档开头计算一次标题的高度。负责此任务的宏称为\beamer@calculateheadfoot
,定义在beamerbaseframecomponents.sty
(第 161-182 行)。如果在演示过程中标题的头部发生变化(顺便说一句,在我看来这不是一个好主意),则必须手动发出此命令。
例如,可以通过将其添加到内部宏来实现\beamer@@@@frame
:像这样,每次构建框架时都会重新计算头线和脚线等:
\usepackage{etoolbox}
\makeatletter
\pretocmd{\beamer@@@@frame}{%
\addtocounter{framenumber}{1}%
\beamer@calculateheadfoot%
\addtocounter{framenumber}{-1}}{}{}
\makeatother
将此代码片段添加到您的文档或主题文件中。(需要手动更改 framenumber
才能获得正确的标题,因为beamer
此时尚未踩下计数器。)
最小示例:
\documentclass{beamer}
% To make a compilable example, these definitions are necessary - you can replace them by your own
\colorlet{LightBlue}{blue}
\colorlet{DarkGray}{gray}
\setbeamercolor{linemid}{bg=green}
\newlength{\headerheight}
\setlength{\headerheight}{10pt}
\makeatletter
\setbeamertemplate{headline}
{ \ifnum\c@framenumber>1
\leavevmode%
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=\headerheight,dp=0pt]{}%
\ifx\insertsection\@empty
\else
{
{\usebeamerfont{headsection}\hspace{1em} \color{LightBlue}\insertsection}
\ifx\insertsubsection\@empty
\else
{\hspace{0.5em}$\vert$ \hspace{0.5em}{\usebeamerfont{headsubsection}\color{DarkGray}\insertsubsection}}%
\fi
}
\fi
\end{beamercolorbox}%
} %
\vskip0pt%
\else
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=20pt,dp=0pt]{linemid}
\end{beamercolorbox}%
}
\fi
}
% Recalculate the head of head- and footlines for each frame
% (http://tex.stackexchange.com/a/61788/3323)
\usepackage{etoolbox}
\makeatletter
\pretocmd{\beamer@@@@frame}{%
\addtocounter{framenumber}{1}%
\beamer@calculateheadfoot%
\addtocounter{framenumber}{-1}}{}{}
\makeatother
\begin{document}
\section{section}
\subsection{subsection}
\frame{Title page with special headline}
\frame{Normal frame}
\frame{Normal frame 2}
\end{document}
答案2
随着当前 beamer 开发版本(应包含在 beamer v3.70 或更新版本中),beamer 现在会在每帧开始时重新计算头部和脚部的高度。
\documentclass{beamer}
% To make a compilable example, these definitions are necessary - you can replace them by your own
\colorlet{LightBlue}{blue}
\colorlet{DarkGray}{gray}
\setbeamercolor{linemid}{bg=green}
\newlength{\headerheight}
\setlength{\headerheight}{10pt}
\makeatletter
\setbeamertemplate{headline}
{ \ifnum\c@framenumber>1
\leavevmode%
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=\headerheight,dp=0pt]{}%
\ifx\insertsection\@empty
\else
{
{\usebeamerfont{headsection}\hspace{1em} \color{LightBlue}\insertsection}
\ifx\insertsubsection\@empty
\else
{\hspace{0.5em}$\vert$ \hspace{0.5em}{\usebeamerfont{headsubsection}\color{DarkGray}\insertsubsection}}%
\fi
}
\fi
\end{beamercolorbox}%
} %
\vskip0pt%
\else
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=20pt,dp=0pt]{linemid}
\end{beamercolorbox}%
}
\fi
}
\begin{document}
\section{section}
\subsection{subsection}
\frame{Title page with special headline}
\frame{Normal frame}
\frame{Normal frame 2}
\end{document}